当前位置:C++技术网 > 资讯 > 实现backup目录功能(没有处理子目录)

实现backup目录功能(没有处理子目录)

更新时间:2016-03-09 11:57:08浏览次数:1+次

  今天学习MFC深入浅出,看到书中有backup目录的程序,但只是给出了其中一些代码,于是自己动手将剩余的代码实现出来,代码如下:

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

struct SRCFILE
{
	WIN32_FIND_DATA fd;
	bool bIsNew;
};
struct DESFILE
{
	WIN32_FIND_DATA fd;
	bool bIsMatch;
};

#define DIRMAX 100
#define FILEMAX 30
#define GetSize(Array) sizeof(Array)/sizeof(Array[0])//获取数组大小,下面的代码没有用到该方法

int GetSrcFileData(TCHAR *strSrcFile, SRCFILE *srcfile);
int GetDesFileData(TCHAR *strDesFile, DESFILE *desfile);

int main()
{
	TCHAR strSrcFile[DIRMAX] = _T("F:\\TestSrc\\*"), strDesFile[DIRMAX] = _T("F:\\TestDes\\*");//原来FindFirstFile和FindNextFile需要的目录参数需要在后面加上\*,意思是遍历所有文件(目录也是文件)
	SRCFILE srcfile[FILEMAX];
	DESFILE desfile[FILEMAX];
	memset(srcfile, 0, sizeof(SRCFILE)*FILEMAX);
	memset(desfile, 0, sizeof(DESFILE)*FILEMAX);
	printf("获取%s目录的文件信息\n", strSrcFile);
	int nSrcFileCount = GetSrcFileData(strSrcFile, srcfile);
	printf("获取%s目录的文件信息\n", strDesFile);
	int nDesFileCount = GetDesFileData(strDesFile, desfile);
	for(int i = 0; i < nSrcFileCount; i++)
	{
		for(int j = 0; j < nDesFileCount; j++)
		{
			LCID Locale = LOCALE_SYSTEM_DEFAULT;
			DWORD dwCmpFlags = NORM_IGNORECASE;
			DWORD cchCount1 = -1;
			DWORD cchCount2 = -1;
			int nResult = CompareString(Locale,dwCmpFlags,srcfile[i].fd.cFileName,cchCount1,desfile[j].fd.cFileName,cchCount2);
			if(nResult == CSTR_EQUAL)
			{
				printf("有相同名字的文件:%s\n", srcfile[i].fd.cFileName);
				int nRet = CompareFileTime(&srcfile[i].fd.ftLastWriteTime, &desfile[j].fd.ftLastWriteTime);
				if(nRet == 0)
				{
					srcfile[i].bIsNew = false;
					printf("两份文件的最后修改时间一致\n");
				}
				else
				{
					printf("两份文件的最后修改时间不一致\n");
				}
				desfile[j].bIsMatch = true;
			}
		}
	}
	TCHAR strSrcDir[DIRMAX] = {0};
	lstrcpyn(strSrcDir, strSrcFile, lstrlen(strSrcFile));
	TCHAR strDesDir[DIRMAX] = {0};
	lstrcpyn(strDesDir, strDesFile, lstrlen(strDesFile));
	for(int i = 0; i < nSrcFileCount; i++)
	{
		if(srcfile[i].bIsNew)
		{
			TCHAR strSrcPath[DIRMAX] = {0};
			lstrcat(strSrcPath, strSrcDir);
			lstrcat(strSrcPath, srcfile[i].fd.cFileName);
			TCHAR strDesPath[DIRMAX] = {0};//strcat的目标字符串最好初始化,不然可能出现意想不到的后果
			lstrcat(strDesPath, strDesDir);
			lstrcat(strDesPath, srcfile[i].fd.cFileName);
			CopyFile(strSrcPath, strDesPath, false);
		}
	}
	for(int i = 0; i < nDesFileCount; i++)
	{
		if(!desfile[i].bIsMatch)
		{
			TCHAR strDesPath[DIRMAX] = {0};
			lstrcat(strDesPath, strDesDir);
			lstrcat(strDesPath, desfile[i].fd.cFileName);
			DeleteFile(strDesPath);
		}
	}
	return 0;
}

int GetSrcFileData(TCHAR *strSrcFile, SRCFILE *srcfile)
{
	WIN32_FIND_DATA fd;
	HANDLE hFile = FindFirstFile(strSrcFile, &fd);
	int nCount = 0;
	if(hFile == INVALID_HANDLE_VALUE) return nCount;
	while(FindNextFile(hFile, &fd) != 0)
	{
		if(fd.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)//目录也是文件,第一个文件是当前目录,第二文件是上层目录
		{
			printf("%s ", fd.cFileName);
			srcfile[nCount].bIsNew = true;
			srcfile[nCount].fd = fd;
			nCount++;
			if(nCount == FILEMAX) break;
		}
	}
	printf("\n");
	FindClose(hFile);
	return nCount;
}

int GetDesFileData(TCHAR *strDesFile, DESFILE *desfile)
{
	WIN32_FIND_DATA fd;
	HANDLE hFile = FindFirstFile(strDesFile, &fd);
	int nCount = 0;
	if(hFile == INVALID_HANDLE_VALUE) return nCount;
	while(FindNextFile(hFile, &fd) != 0)
	{
		if(fd.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
		{
			printf("%s ", fd.cFileName);
			desfile[nCount].bIsMatch = false;
			desfile[nCount].fd = fd;
			nCount++;
			if(nCount == FILEMAX) break;
		}
	}
	printf("\n");
	FindClose(hFile);
	return nCount;
}
  注意,加注释的地方是容易出错的地方,第一个是FindFirstFile的目录参数,目录参数后面一定要加上\*,表示搜索该目录下的所有文件,如果只是目录地址,那么就只会搜索这个目录文件而已,不会搜索里面的文件。

  第二是strcat的目标字符串最好初始化,否则可能出现意想不到的后果,我之前没有初始化,导致字符串少了字符F,导致程序结束后出现字符串数组越界问题。

  第三是目录也是文件,所以搜索目录下的文件需要进行判断,是否是存储文件,存储文件才是我们想要backup的文件。

  补充一点,上面的程序没有实现搜索子目录的功能,也就是说没有实现backup整个目录,只是backup了这个目录下的文件,如果大家有兴趣,可以去实现,并且分享出来,共同进步,如果我的代码有什么不好的地方,欢迎留言。