windows 遍历目录下的所有文件 FindFirstFile FindNextFile

时间:2023-03-09 18:21:12
windows 遍历目录下的所有文件 FindFirstFile FindNextFile

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); }