解决windows下c++删除文件超长路径失败

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