Windows下遍歷文件時用到的就是FindFirstFile 和FindNextFile 首先看一下定義:
HANDLE FindFirstFile( LPCTSTR lpFileName, // file name LPWIN32_FIND_DATA lpFindFileData // data buffer );
函數成功時,返回一個有效句柄,失敗時返回INVALID_HANDLE_VALUE
參數說明:
lpFileName:文件名,可以用通配符來指定遍歷的文件類型,例如*.*表示所有文件, *.txt表示匹配所有的文本文件。還可以用?,?表示任意一個字符
lpFindData:是一個WIN32_FIND_DATA的結構,該結構說明了遍歷到文件或者子目錄的的屬性,看一下定義:
typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; //文件屬性,例如是目錄還是文件, 是隱藏文件,加密文件, 只讀文件等等 FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; //文件大小的高32位,一般為0,即不超過4GB DWORD nFileSizeLow; //文件大小的低32位 DWORD dwReserved0; DWORD dwReserved1; TCHAR cFileName[ MAX_PATH ]; //文件名,不包括路徑 TCHAR cAlternateFileName[ 14 ]; } WIN32_FIND_DATA, *PWIN32_FIND_DATA;
這個結構體的參數不多介紹了。
看下一個函數:
BOOL FindNextFile( HANDLE hFindFile, // search handle LPWIN32_FIND_DATA lpFindFileData // data buffer );參數說明:
hFindFile:為FindFirstFile返回的句柄, 第二個參數和前面的一樣,
返回值:成功返回1,失敗返回0. 調用GetLastError()可查看錯誤代碼
這里寫兩個函數練習,
第一個將傳入目錄下的所有文件以及子目錄下所有的文件都加上.temp
第二個函數將刪除傳入目錄的所有文件以及子目錄下所有的文件后綴名為.txt 的文件
void RenameAndDelFile(const string &strPath) { string strRawPath = strPath; strRawPath.append("\\"); string strFindPath = strRawPath; strFindPath.append("*.*"); WIN32_FIND_DATAA winFindData; HANDLE hTemp = FindFirstFileA(strFindPath.c_str(), &winFindData); if (INVALID_HANDLE_VALUE == hTemp) return ; while (FindNextFileA(hTemp, &winFindData)) { string strOldName = winFindData.cFileName; if ("." == strOldName || ".." == strOldName) continue; //如果是目錄,則遞歸繼續操作 if (winFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { string strAgain = strPath; strAgain.append("\\"); strAgain.append(winFindData.cFileName); RenameAndDelFile(strAgain); continue; } //獲得絕對路徑 strOldName = strRawPath; strOldName.append(winFindData.cFileName); string strNewName = strOldName; strNewName.append(".temp"); //更名以及刪除文件 rename(strOldName.c_str(), strNewName.c_str()); //DeleteFileA(strNewName.c_str()); } FindClose(hTemp); } void DeleteTXTFile(const string &strPath) { string strRawPath = strPath; strRawPath.append("\\"); string strFindPath = strRawPath; strFindPath.append("*.*"); WIN32_FIND_DATAA winFindData; HANDLE hTemp = FindFirstFileA(strFindPath.c_str(), &winFindData); if (INVALID_HANDLE_VALUE == hTemp) return; while (FindNextFileA(hTemp, &winFindData)) { string strOldName = winFindData.cFileName; if ("." == strOldName || ".." == strOldName) continue; //如果是目錄,則遞歸繼續操作 if (winFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { string strAgain = strPath; strAgain.append("\\"); strAgain.append(winFindData.cFileName); DeleteTempFile(strAgain); continue; } string strDel = strRawPath; strDel.append(strOldName); char szDrive[MAX_PATH] = {0}; char szDir[MAX_PATH] = {0}; char szFileName[MAX_PATH] = {0}; char szExt[MAX_PATH] = {0}; _splitpath_s(strDel.c_str(), szDrive, MAX_PATH, szDir, MAX_PATH, szFileName, MAX_PATH, szExt, MAX_PATH); if (strcmp(".txt", szExt) == 0) DeleteFileA(strDel.c_str()); } FindClose(hTemp); }