想要进行文件/目录的监测、创建、删除等操作,有好几种函数可以实现,但因为不同操作系统不兼容,可能同一个函数在linux可用,windows就不可用,而windows本身又有ansi、utf8、unicode好几种编码,所有函数都支持ANSI路径也就是纯英文路径,但遇到中文路径大部分操作函数就失效,简直乱成一锅粥。
这里做个备忘录,整理一下windows下可用的文件/目录操作函数。
优先使用宽字符集版本函数
比如_stat函数有_stat()和_wstat()宽字符集版本,优先使用宽字符集版本,以便更好的支持中文路径或其他非ANSI语言。
判断文件或目录是否存在
_waccess_s()或_stat()都可以,_waccess_s()更简便。
_waccess_s
_waccess_s()是_access()函数的宽字符集更安全版本,可判断文件或目录是否存在(官方链接)。
返回值,0=存在,2=不存在。
1 2 3 4 5 6 7 | // 文件 if (_waccess_s(L"c:\test\test.exe", 0) == 0) // 目录 if (_waccess_s(L"c:\test", 0) == 0) // 用变量 wstring path(L"c:\\test\\test.exe"); if (_waccess_s(path.data(), 0) == 0) |
_stat
_stat()也可以判断文件或目录是否存在(官方链接),但是用此函数需要先申明一个结构体变量用于保存文件的详细权限,只用于判断文件是否存在是没必要这么麻烦。
另外不带下划线的stat()函数只能对纯英文路径判断,不能判断带中文的路径,我在此载坑了很久。
创建目录
CreateDirectory(L"c:\test", nullptr);
CreateDirectory(wstring.data(), nullptr);
移动文件
MoveFile(wstring_filepath.data(), wstring_newpath.data());
复制文件
CopyFile(wstring_filepath.data(), wstring_newpath.data(), FALSE);
删除文件
DeleteFile(wstring_filepath.data());
重命名
网上介绍的rename()函数不支持中文。我直接用复制后删除。
if (_waccess_s(wstring_filepath.data(), 0) == 0) {
if (CopyFile(wstring_filepath.data(), wstring_newfilepath.data().data(), FALSE))
DeleteFile(wstring_filepath.data().data());
}
删除目录
因为函数只能删除空目录,因为可以直接写一个封装函数遍历删除目录内的所有文件和子目录。需要删除目录的时候直接调用此函数即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | void RemoveAllFiles(const wstring& wstrDir) { if (wstrDir.empty()) { return; } WIN32_FIND_DATA findData; const wstring wstrTempDir = wstrDir + L"\\*"; const HANDLE 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); } else { DeleteFile(wstrFileName.c_str()); } } while (FindNextFile(hFind, &findData)); FindClose(hFind); RemoveDirectory(wstrDir.c_str()); } |
文章评论