目录
3.使用递归遍历指定目录下的所有文件(包括子目录中的文件)和目录(包括子目录中的目录)
1.使用 FindFirstFile和FindNextFile
本文中的代码用的是Unicode字符集,所以参数需要用宽字符
一、FindFirstFile
1.函数功能:
在目录中搜索与指定名称(如果使用通配符则为部分名称)相匹配的文件或子目录
2.函数原型:
HANDLE FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATAW lpFindFileData
);
3.参数:
lpFileName
- 目录或路径,以及文件名。文件名可以包含通配符,例如,星号(*)或问号(?).
- 此参数不能为NULL,无效字符串(例如,空字符串或者缺少结束符'\0'的字符串),或者以反斜杠(\)结尾
lpFindFileData
- 指向结构体WIN32_FIND_DATA的指针,该结构体用来接收找到的文件或者目录的信息
4.返回值:
- 如果函数成功,则返回值将在随后的FindNextFile 或FindClose函数调用中使用的搜索句柄,并且lpFindFileData 参数包含找到的第一个文件或目录的信息。
- 如果函数失败或者无法从lpFileName参数的搜索字符串中找到文件,则返回值为INVALID_HANDLE_VALUE ,并且lpFindFileData的内容不确定。
- 如果该函数由于找不到匹配的文件而失败,则GetLastError 函数将返回ERROR_FILE_NOT_FOUND。
5.注意:
FindFirstFile函数打开一个搜索句柄,并返回文件系统通过和指定的模式匹配的名字找到的第一个文件的信息。当使用相同的文件名字符串模式时,这可能是也可能不是出现在目录列表应用程序(例如dir命令)中的的第一个目录,因为FindFirstFile部队搜索结果进行排序。
以下列表为一些其他的搜索特点:
- 搜索仅在文件名上执行,而不在日期或者文件类型之类的其他属性上执行(有关其他选项,请参见FindFirstFileEx)
- 为lpFileName 参数传递无效的字符串,NULL,或者空字符串不是该函数的有效用法。在这种情况下结果是不确定的。
建立搜索句柄后,可以使用FindNextFile函数来搜索与同样模式匹配的其他文件。
当不再需要搜索句柄时,请使用FindClose函数(而不是CloseHandle)将其关闭。
如前所述,不能在输入参数lpFileName 字符串末尾使用反斜杠\,因此如何搜索根目录可能并不明显。如果要查看文件或者获取根目录的属性,则可以使用以下选项:
- 要检查目录中的文件,可以使用"C:\*",并使用FindNextFile逐步浏览目录。
二、FindNextFile
1.函数功能:
从前面对函数FindFirstFile, FindFirstFileEx, 或者FindFirstFileTransacted的调用后,继续文件搜索。
2.函数原型:
BOOL FindNextFileW(
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData
);
3.参数:
hFindFile
从前面对函数FindFirstFile或FindFirstFileEx的调用返回的搜索句柄。
lpFindFileData
指向结构体WIN32_FIND_DATA的指针,该结构体用来接收找到的文件或者子目录的信息
4.返回值:
- 如果函数成功,则返回值为非0,并且参数lpFindFileData包含找到的下一个文件或目录的信息。
- 如果函数失败,则返回值为0,并且lpFindFileData的内容不确定。若要获取更多的错误信息,请调用GetLastError函数。
- 如果该函数由于找不到更多匹配文件而失败,则GetLastError函数将返回ERROR_NO_MORE_FILES。
5.注意:
该函数使用的搜索过滤器,和用来创建搜索句柄的过滤器相同。搜索句柄是通过参数hFindFile传过来的。
三、遍历指定目录下的所有文件和子目录
- 要查看H:\miniprogram目录中的所有直接文件和目录,应该使用H:\miniprogram\*,而不是H:\miniprogram或H:\miniprogram\
- 需要使用转义字符H:\\miniprogram\\*
- FindFirstFile() 返回HANDLE类型,为下一次搜索提供搜索句柄。当搜索失败时,返回INVALID_HANDLE_VALUE
- FindNextFile() ,用于搜索下一个文件,当不存在下一个文件,即搜索完毕后,返回0
- 通常,最初的两次搜索得到的文件名为:"." 、"..",分别代表当前目录和上级目录
1.查看指定目录中的所有直接文件和目录
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
void ListFilesInDirectory(wstring wstrDir)
{
if (wstrDir.empty())
{
return;
}
HANDLE hFind;
WIN32_FIND_DATA findData;
wstring wstrTempDir = wstrDir + (L"\\*");
hFind = FindFirstFile(wstrTempDir.c_str(), &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
do
{
wstring wstrFileName;
wstrFileName.assign(wstrDir);
wstrFileName.append(L"\\");
wstrFileName.append(findData.cFileName);
wcout << wstrFileName << endl;
} while (FindNextFile(hFind, &findData)!= 0);
FindClose(hFind);
}
int main()
{
ListFilesInDirectory(L"H:\\miniprogram");
return 0;
}
目录内容如下:
程序输出如下:
得到文件夹中所有以.json结尾的文件
wstring wstrTempDir = wstrDir + (L"\\*.json");
2.过滤.和..
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
void ListFilesInDirectory(wstring wstrDir)
{
if (wstrDir.empty())
{
return;
}
HANDLE hFind;
WIN32_FIND_DATA findData;
wstring wstrTempDir = wstrDir + (L"\\*");
hFind = FindFirstFile(wstrTempDir.c_str(), &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
do
{
// 忽略"."和".."两个结果
if (wcscmp(findData.cFileName, L".") == 0 || wcscmp(findData.cFileName, L"..") == 0)
{
continue;
}
wstring wstrFileName;
wstrFileName.assign(wstrDir);
wstrFileName.append(L"\\");
wstrFileName.append(findData.cFileName);
wcout << wstrFileName << endl;
} while (FindNextFile(hFind, &findData)!= 0);
FindClose(hFind);
}
int main()
{
ListFilesInDirectory(L"H:\\miniprogram");
return 0;
}
3.使用递归遍历指定目录下的所有文件(包括子目录中的文件)和目录(包括子目录中的目录)
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
void ListFilesInDirectory(wstring wstrDir)
{
if (wstrDir.empty())
{
return;
}
HANDLE hFind;
WIN32_FIND_DATA findData;
wstring wstrTempDir = wstrDir + (L"\\*");
hFind = FindFirstFile(wstrTempDir.c_str(), &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
do
{
// 忽略"."和".."两个结果
if (wcscmp(findData.cFileName, L".") == 0 || wcscmp(findData.cFileName, L"..") == 0)
{
continue;
}
wstring wstrFileName;
wstrFileName.assign(wstrDir);
wstrFileName.append(L"\\");
wstrFileName.append(findData.cFileName);
wcout << wstrFileName << endl;
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)// 是否是目录
{
ListFilesInDirectory(wstrFileName.c_str());
}
} while (FindNextFile(hFind, &findData)!= 0);
FindClose(hFind);
}
int main()
{
ListFilesInDirectory(L"H:\\miniprogram");
return 0;
}
四、删除目录,包括该目录下所有子目录和文件
1.使用 FindFirstFile和FindNextFile
- RemoveDirectory只能删除空目录
- DeleteFile只能删除文件
- 过滤掉"."和".."
- 先遍历当前目录中的文件,若为文件就删除,若为文件夹,将文件夹名追加到末尾作为新的目录去递归
- 每次函数结束之前要删除当前目录
- 假设删除时,某文件正在被使用,则该文件和其所属目录无法被删除,但不影响其他未被使用的文件的删除
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
void RemoveAllFiles(wstring wstrDir)
{
if (wstrDir.empty())
{
return;
}
HANDLE hFind;
WIN32_FIND_DATA findData;
wstring wstrTempDir = wstrDir + (L"\\*");;
hFind = FindFirstFile(wstrTempDir.c_str(), &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
do
{
// 忽略"."和".."两个结果
if (wcscmp(findData.cFileName, L".") == 0 || wcscmp(findData.cFileName, L"..") == 0)
{
continue;
}
wstring wstrFileName;
wstrFileName.assign(wstrDir);
wstrFileName.append(L"\\");
wstrFileName.append(findData.cFileName);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)// 是否是目录
{
RemoveAllFiles(wstrFileName.c_str());
}
else
{
DeleteFile(wstrFileName.c_str());
}
} while (FindNextFile(hFind, &findData));
FindClose(hFind);
RemoveDirectory(wstrDir.c_str());
}
int main()
{
RemoveAllFiles(L"H:\\miniprogram");
return 0;
}
2.使用SHFileOperation
能直接删除掉目录和该目录下的所有文件和子目录,但是假如该目录下有文件正在被使用,则函数执行失败,一个文件都没被删掉。
SHFILEOPSTRUCT FileOp;
FileOp.fFlags = FOF_NOCONFIRMATION;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = L"H:\\miniprogram";
FileOp.pTo = NULL;
FileOp.wFunc = FO_DELETE;
SHFileOperation(&FileOp);
参考:
1. https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilew FindFirstFileW function (fileapi.h)
2. https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextfilew FindNextFileW function (fileapi.h)
3. https://docs.microsoft.com/en-us/windows/win32/fileio/listing-the-files-in-a-directory Listing the Files in a Directory
4. https://blog.csdn.net/WNDCLASSEXW/article/details/86614171 C++遍历删除指定目录下所有文件和文件夹(包括自身)
5. https://blog.csdn.net/u012005313/article/details/46490437 利用FindFirstFile(),FindNextFile()函数历遍指定目录的所有文件
6. http://www.360doc.com/content/11/1102/17/992979_161139651.shtml FindFirstFile的正确用法
7. https://blog.csdn.net/veryhehe2011/article/details/7769814 FindFirstFile()函数
8. https://blog.csdn.net/weixin_40332490/article/details/105306620 FindFirstFile()