今天学习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了这个目录下的文件,如果大家有兴趣,可以去实现,并且分享出来,共同进步,如果我的代码有什么不好的地方,欢迎留言。