使用vc++MFC如何在整个磁盘硬盘中查找文件?
使用MFC如何在整个磁盘硬盘中查找文件?
在ANSI C中文件查找通过findfirst和findnext函数进行。在Win32中提供了专门的文件查找的函数,
HANDLE FindFirstFile( LPCTSTR lpFileName, // file name LPWIN32_FIND_DATA lpFindFileData // data buffer ); BOOL FindNextFile( HANDLE hFindFile, // search handle LPWIN32_FIND_DATA lpFindFileData // data buffer ); BOOL FindClose( HANDLE hFindFile // file search handle );
在开始文件查找时先调用FindFirstFile,同时提供一个需要查找的文件名,该文件名中可以有通配符号* ?,而lpFindFileData是作为输出参数,该参数的具体内容后面再讲。如果查找失败将返回 INVALID_HANDLE_VALUE,如果查找成功函数将返回一个句柄,并且有系统填充lpFindFileData参数所指向的结构。在第一次查找成功后利用返回的句柄和lpFindFileData参数来调用FindNextFile,如果能够找到下一个匹配的文件函数会返回TRUE,否则返回FALSE。在查找结束后调用FindClose关闭句柄。示范代码如下:
WIN32_FIND_DATA ffd ; HANDLE hFind = FindFirstFile("c://windows//*.txt",&ffd); if (hFind != INVALID_HANDLE_VALUE) { //处理第一个找到的文件 while(FindNextFile(hFind,&ffd)) { //your code ... 处理其他被找到的文件 } FindClose(hFind); }
在文件查找中核心部分就是 WIN32_FIND_DATA 结构,在使用这个结构时请记住不要手工修改这个结构中的任何数据,结构对于开发人员来将只能作为一个只读数据,所有字段都会由系统填写,结构内容如下:
typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; //文件属性 FILETIME ftCreationTime; // 文件创建时间 FILETIME ftLastAccessTime; // 文件最后一次访问时间 FILETIME ftLastWriteTime; // 文件最后一次修改时间 DWORD nFileSizeHigh; // 文件长度高32位 DWORD nFileSizeLow; // 文件长度低32位 DWORD dwReserved0; // 系统保留 DWORD dwReserved1; // 系统保留 TCHAR cFileName[ MAX_PATH ]; // 长文件名 TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名 } WIN32_FIND_DATA, *PWIN32_FIND_DATA;
dwFileAttributesw为文件属性,可以是以下数据的按位组合。
- FILE_ATTRIBUTE_ARCHIVE 归档文件或目录
- FILE_ATTRIBUTE_COMPRESSED 压缩文件或目录
- FILE_ATTRIBUTE_DIRECTORY 目录
- FILE_ATTRIBUTE_ENCRYPTED 加密文件或目录
- FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录
- FILE_ATTRIBUTE_NORMAL 文件或目录的属性没有被设置,这个属性只能单独出现
- FILE_ATTRIBUTE_READONLY 只读文件或目录
- FILE_ATTRIBUTE_SYSTEM 系统文件或目录
- FILE_ATTRIBUTE_TEMPORARY 临时文件或目录
Win32提供的文件查找功能无法对子目录进行嵌套查找,而只能对你指定的目录进行查找,如果希望查找子目录下所有文件则需要自己开发子目录查找功能。例如下面的代码可以遍历指定目录下的所有目录,相当与命令 dir c:/ /D /S
//调用方式 Dir_A_S("c://"); void Dir_A_S(LPCSTR pszDir) { printf("%s/n",pszDir); WIN32_FIND_DATA ffd ; char szDirFile[1024]; sprintf(szDirFile,"%s*",pszDir); HANDLE hFind = FindFirstFile(szDirFile,&ffd); if (hFind != INVALID_HANDLE_VALUE) { char szDir[1024]; if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,"..")) {//确定找到一个目录并且不为 . 或 .. sprintf(szDir,"%s%s//",pszDir,ffd.cFileName); Dir_A_S(szDir); } while(FindNextFile(hFind,&ffd)) { if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,"..")) {//确定找到一个目录并且不为 . 或 .. sprintf(szDir,"%s%s//",pszDir,ffd.cFileName); //printf("%s/n",szDir); Dir_A_S(szDir); } } FindClose(hFind); } }
文件查找还有一个其他的用法就是用来确定文件是否存在,你可以使用下面的函数。
BOOL IsFileExist(LPCSTR pszFileName) { WIN32_FIND_DATA FindFileData; HANDLE hFind; hFind = FindFirstFile(pszFileName, &FindFileData); if (hFind == INVALID_HANDLE_VALUE) return FALSE; else { FindClose(hFind); return TRUE; } }
如果你使用MFC进行开发,可以使用CFileFind类来进行文件查找,MFC完整的封装了文件查找的功能。用于文件查找的成员函数为:
virtual BOOL FindFile( LPCTSTR pstrName = NULL, DWORD dwUnused = 0 ); 开始查询 virtual BOOL FindNextFile( ); 查找文件,对于第一个文件和下一个文件都通过这个函数进行查询 //下面是一段文件查找演示代码 CFileFind finder; strWildcard += _T("//*.*"); BOOL bWorking = finder.FindFile(strWildcard); while (bWorking) { bWorking = finder.FindNextFile(); //你自己的处理代码 } finder.Close(); 同时在CFileFind中封装了很多判断函数用于确定文件的各种属性,这些函数是 GetLength 得到文件长度 GetFileName 得到文件名 GetFilePath 得到文件路径名和文件名 GetCreationTime / GetLastAccessTime / GetLastWriteTime 得到文件时间 IsDots 判断文件是否为 . 或 .. IsReadOnly / IsDirectory / IsCompressed / IsSystem / IsHidden / IsTemporary / IsNormal /IsArchived 得到文件属性 //下面是一个用MFC中CFileFind类实现的目录遍历功能 // 调用方式为 MFC_Dir_A_S("c://") void MFC_Dir_A_S(LPCSTR pszDir) { printf("%s/n",pszDir); CFileFind ff; char szDirFile[1024]; sprintf(szDirFile,"%s*",pszDir); if (ff.FindFile(szDirFile)) { char szDir[1024]; while(ff.FindNextFile()) { if(ff.IsDirectory() && ! ff.IsDots()) {//确定找到一个目录并且不为 . 或 .. sprintf(szDir,"%s%s//",pszDir,ff.GetFileName()); //printf("%s/n",szDir); MFC_Dir_A_S(szDir); } } ff.Close();//关闭 } }
欢迎讨论,相互学习。
cdtxw@foxmail.com