1. 程式人生 > >C語言(遞迴遍歷資料夾)實現檔案批量複製

C語言(遞迴遍歷資料夾)實現檔案批量複製

大專案時時常需要抽出屬於自己編寫的那部分程式碼,從SVN下載後,往往需要一個個的進入資料夾下拿取相應的檔案。這樣很浪費時間,雖然使用bat編寫確實更快,但是我覺得使用C語言可能在檔案過多時會快一點,也是為了 練習練習。如果那裡存在問題,或是不足,歡迎指出。程式碼如下:


#include<stdio.h>
#include<io.h>
#include<string.h>
#include<direct.h>
#include<errno.h>

#include<stdio.h>
#include<io.h>
#include<string.h>
#include<direct.h>
#include<errno.h>
/*
   1.檔案批處理的快速操作,
   2.當前電腦中不存在的功能
   3.實用性較高
   4.速度較快
   5.需求功能
     5.1 大資料夾下搜尋指定檔名檔案  複製到指定對應檔案路徑下        部分檔案指定複製  是否覆蓋大
	 5.2 資料夾下搜尋指定檔名檔案  複製到某個資料夾下             模糊抽出功能

*/

/*
字串匹配演算法
*/
int Inquire_filaname(char *src, char *dest)
{
	int i = 0, j = 0;
	int srclen = 0, destlen = 0;
	srclen = strlen(src);
	destlen = strlen(dest);

	if (srclen < destlen)
	{
		return -1;
	}

	while (i < srclen && j < destlen)
	{
		if (src[i] == dest[j])
		{
			i++;
			j++;
		}
		else
		{
			i = i - j + 1;
			j = 0;
		}
	}
	if (j >= destlen)
	{
		return i - j;
	}
	else
	{
		return -1;
	}
}

/*
將Inpath路徑的檔案,複製到Outpath的路徑中
*/
int WriteFile(char *Inpath, char *Outpath)
{
	FILE *Infile=NULL ;
	FILE *Outfile =NULL;

	char str[1024] ;
	if (Inpath != NULL && Outpath != NULL)
	{
		Infile = fopen(Inpath, "rb");
		Outfile = fopen(Outpath, "wb");
		if (Infile != NULL)
		{
			if (Outfile != NULL)
			{
				//printf("%c", getc(Infile));
				while (fread(str, sizeof(str),1 , Infile) != NULL)
				{
					fwrite(str, sizeof(str),1, Outfile);
				}
			}

			fclose(Outfile);
			fclose(Infile);
		    Infile = NULL;
			Outfile = NULL;
			return 2;
		}
	}
		return 0;
}

/*
指定搜尋目錄
指定目的目錄
指定搜尋檔名 
指定搜尋型別
*/
int File_out(char *SrcPath, char *filename,char *DestPath, char *type)
{
	int  a = atoi(type);
	if (SrcPath != NULL && DestPath != NULL) // 如果指定大 檔案目錄存在
	{
		_mkdir(DestPath);
		
		// type ==1  5.1    type == 2   5.2
		FileSearch(SrcPath, filename, DestPath, a);
	}
	else
	{
		printf("請輸入輸入路徑或輸入路徑");
		return 0;
	}
}

int FileSearch(char *dir, char *filename, char *copypath, int type)//遞迴遍歷當前目錄下的所有檔案
{
	char dirNew[200];
	int Isnull = 0;  //資料夾中是否有符合的檔案,0為沒有,1為有
	char path_A[200];  //儲存檔案路徑
	char path_B[200]; //儲存資料夾路徑

	strcpy(dirNew, dir);

	strcat(dirNew, "\\*.*");  // 修改此處改變搜尋條件 
	struct _finddata_t filefind;

	int done = 0, i, handle;

	if ((handle = _findfirst(dirNew, &filefind)) != -1)
	{
		while (!(done = _findnext(handle, &filefind)))
		{
			strcpy(path_A, dir);

			strcpy(path_B, copypath);

			if (strcmp(filefind.name, "..") == 0)
				continue;
			printf("當前工作目錄 is \"%s\"\n", dir);
			printf("當前目的目錄 is \"%s\"\n", copypath);
			if ((_A_SUBDIR == filefind.attrib))				// 是目錄
			{

				//printf("當前工作目錄 is \"%s\"\n", dirNew);
				//擷取最後路徑/
				
				if (type == 1)
				{
					strcat(path_B, "\\");
					strcat(path_B, filefind.name);
					_mkdir(path_B);
				}

				strcat(path_A, "\\");
				strcat(path_A, filefind.name);
				if (1 == FileSearch(path_A, filename, path_B, type))// 遞迴遍歷子目錄
				{
					memset(path_A, '\0', sizeof(path_A));
					memset(path_B, '\0', sizeof(path_B));
					strcpy(path_A, dir);
					strcpy(path_B, copypath);
				}
			}
			else
			{
				if (-1 != Inquire_filaname(filefind.name, filename))
				{
					//printf("[File]:\t%s\n", filefind.name);  
					//如果是5.1,則在之前建立的資料夾下,複製檔案
					if (type == 1)
					{
						strcat(path_B, "\\");
						strcat(path_B, filefind.name);
						//copypath = path_B;
						//printf("[copypath]:\t%s\n", copypath);

					}
					else
					{
						//如果是5.2,則直接在總路徑下複製路徑檔案,
						strcat(path_B, "\\");
						strcat(path_B, filefind.name);
						//copypath = path_B;

					}

					strcat(path_A, "\\");
					strcat(path_A, filefind.name);
					//(copypath, filefind.name);
					printf("[path_A]:\t%s\n", path_A);
					printf("[path_B]:\t%s\n", path_B);
					if (WriteFile(path_A, path_B) != 0)
					{
						Isnull = 1;
					}

				}
				
			}
		}
		_findclose(handle);

         //如果出現空資料夾或不是2型別,則刪除空資料夾
		if (Isnull == 0 && 1 == type)
		{
			_rmdir(copypath);
		}
		return 1;
	}

	return 0;
}

int main(int argc, char **argv)
{
	File_out(dirname, dirname1, filename, argv[4]);
	return 0;
}