Jon*_*ood 1 c++ windows winapi mfc delete-file
我正在写一个有错误的备份程序.使用调试器逐步执行代码,我发现删除文件时出错.
我CFileFind用来找到文件,我CFileFind::GetFilePath()用来获取完整的路径名.
CFileFind find;
BOOL bContinue = find.FindFile(AppendPath(lpszPath, _T("*")));
while (bContinue)
{
bContinue = find.FindNextFile();
if (!find.IsDirectory())
{
if (find.IsReadOnly())
ClearReadOnlyAttribute(find);
if (!::DeleteFile(find.GetFilePath()))
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
DeleteFile()正在返回FALSE,并GetLastError()返回3(ERROR_PATH_NOT_FOUND),在其他情况下返回2(ERROR_FILE_NOT_FOUND).
如您所见,我首先尝试删除只读属性(如果已设置); 但是,我可以看到该文件存在且它没有只读属性.
需要注意的一点是文件名很长.这段代码实际上经过了测试,并且在较短的文件名下运行良好.在这种情况下,find.GetFilePath()返回:
\\ Readyshare\USB 3\Backups\DRIVEZ_BACKUP\Stacey\Backup 0001\Music\TO BE DELETED\iTunes\iTunes Media\Music\Dave Matthews Band \远离世界(豪华版)\远离世界(豪华版). itlp \音频\ DaveMatthewsBand_AwayFromTheWorld_backgroundaudio.m4a
这看起来是正确的.如果我将除文件名以外的所有文件复制到Windows资源管理器中,它会显示该文件夹 该文件存在于该文件夹中.
有谁知道为什么DeleteFile()会告诉我路径或文件不存在,实际上它确实存在?
更新:
基于Bruno Ferreira的回答,我通过以下方法运行我的文件名.(对不起旧的CString风格的代码,我正在更新旧的MFC程序.)
CString CBackupWorker::ConvertToExtendedLengthPath(LPCTSTR pszPath)
{
CString s(pszPath);
if (s.GetLength() >= MAX_PATH)
{
if (::isalpha(s[0]) && s[1] == ':')
{
s.Insert(0, _T("\\\\?\\"));
}
else if (s[0] == '\\' && s[1] == '\\')
{
s.Delete(0, 2);
s.Insert(0, _T("\\\\\?\\UNC\\"));
}
}
return s;
}
Run Code Online (Sandbox Code Playgroud)
正如您可以看到的那样,如果文件名超出,则在前面添加适当的前缀MAX_PATH.根据路径是否指定网络路径,采取步骤附加适当的前缀.
我不知道为什么这个令人难以置信的凌乱.如果Windows允许您指定更长的名称,我真的看不到向后兼容性问题.在Windows 10上,您可以更改注册表设置,以便不需要这种废话.但是,当然,我不想将我的软件限制为只调整版本的Windows 10.
来自MSDN:
参数
lpFileName [in]要删除的文件的名称.在此函数的ANSI版本中,名称仅限于MAX_PATH字符.要将此限制扩展为32,767个宽字符,请调用该函数的Unicode版本并在路径前加上"\\?\".有关更多信息,请参阅命名文件.
基本上,您应该为本地路径和远程路径调用DeleteFileW前置,如下所示:\\?\\\?\UNC\
CFileFind find;
BOOL bContinue = find.FindFile(AppendPath(lpszPath, _T("*")));
while (bContinue)
{
bContinue = find.FindNextFile();
if (!find.IsDirectory())
{
if (find.IsReadOnly())
ClearReadOnlyAttribute(find);
CString path = find.GetFilePath();
if (path.GetLength() >= MAX_PATH)
{
if (PathIsUNC(path)) {
path.TrimLeft(_T("\\"));
path.Insert(0, _T("\\\\?\\UNC\\"));
}
else
path.Insert(0, _T("\\\\?\\"));
}
if (!::DeleteFileW(path))
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
509 次 |
| 最近记录: |