在c++中删除超长路径文件会导致失败,根据https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilew,本人写的接口DeleteDir能成功解决此问题。话不多说,附上相关代码
void StringToWstring(std::wstring& szDst, std::string str) { std::string temp = str; int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)temp.c_str(), -1, NULL, 0); wchar_t * wszUtf8 = new wchar_t[len + 1]; memset(wszUtf8, 0, len * 2 + 2); MultiByteToWideChar(CP_ACP, 0, (LPCSTR)temp.c_str(), -1, (LPWSTR)wszUtf8, len); szDst = wszUtf8; std::wstring r = wszUtf8; delete[] wszUtf8; }
//路径中的/转为反双斜杠 void replace_string_path(std::string& str) { std::string old_value = "/"; std::string new_value = "\\"; while (true) { std::string::size_type pos(0); if ((pos = str.find(old_value)) != std::string::npos) { str.replace(pos, old_value.length(), new_value); } else { break; } } }
//删除不可逆 可能返回失败文件只删除一部分(删除掉所有能删除的数据) 返回成功是全部都删除 bool DeleteDir(const std::string &szFileDir, bool delete_self) { if (_access(szFileDir.c_str(), 0) == -1) return true; bool del_success = true; std::string strDir = szFileDir + "/"; std::vector<std::string> list;
std::string path_f = szFileDir + "/*"; WIN32_FIND_DATAA FindFileData; HANDLE hFind;
hFind = FindFirstFileA((LPCSTR)path_f.c_str(), &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { return false; } else { do { if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL || FindFileData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE || FindFileData.dwFileAttributes == FILE_ATTRIBUTE_HIDDEN || FindFileData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM || FindFileData.dwFileAttributes == FILE_ATTRIBUTE_READONLY) { char* fname; fname = FindFileData.cFileName;
std::string file_path = strDir + std::string(fname); if (!DeleteFileA((LPCSTR)file_path.c_str())) {//删除失败有可能是路径为超长路径 std::string prefix_path = "\\\\?\\"; replace_string_path(file_path); prefix_path += file_path; std::wstring file_path_w; StringToWstring(file_path_w, prefix_path); if (!DeleteFileW((LPCWSTR)file_path_w.c_str())) { del_success = false; } } } else if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0) { char* fname; fname = FindFileData.cFileName; std::string file_path = strDir + std::string(fname); if (!DeleteDir(file_path)) { del_success = false; } } } while (FindNextFileA(hFind, &FindFileData));
FindClose(hFind); }
std::string strDir_temp = std::string(szFileDir); if (delete_self) { if (!RemoveDirectoryA((LPCSTR)strDir_temp.c_str())) { del_success = false; } }
return del_success; }