我在写一个有错误的备份程序。用调试器遍历代码,我发现删除文件时出现错误。DeleteFile()失败,但文件存在(很长的文件名)
我使用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;
}
}
DeleteFile()
正在返回FALSE
,和GetLastError()
将返回3(ERROR_PATH_NOT_FOUND
),并且是在其它情况下返回图2(ERROR_FILE_NOT_FOUND
)。
正如你所看到的,我第一次尝试删除只读属性,如果它被设置;但是,我可以看到文件存在并且没有只读属性。
有一点要注意的是,文件名非常长。这段代码实际上已经过测试,并且工作得很好,文件名较短。在这种情况下,find.GetFilePath()
回报:
\\ Readyshare \ USB 3 \备份\ DRIVEZ_BACKUP \斯泰西\备份0001 \音乐\将被删除\ iTunes的\ iTunes的媒体\音乐\戴夫·马修斯乐队\距世界(豪华版)\远离世界(豪华Version.itlp \音频\ DaveMatthewsBand_AwayFromTheWorld_backgroundaudio.m4a
,这看起来是正确的。如果我复制所有但文件名到Windows资源管理器,它让我看到该文件夹。而文件夹中存在那里。
有谁知道为什么DeleteFile()
事实上它会告诉我路径或文件不存在吗?
UPDATE:
基于布鲁诺·费雷拉的回答,我通过以下方法运行我的文件名。 (对不起,老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;
}
正如你所看到的代码,如果文件名超过MAX_PATH
预先考虑相应的前缀。根据路径是否指定网络路径,采取步骤追加适当的前缀。
我不知道为什么有人做这个令人难以置信的混乱。如果Windows允许您指定更长的名称,我真的不会看到向后兼容性问题。在Windows 10中,有一个注册表设置可以更改,这样就不需要这个废话。但当然,我不希望我的软件限制到Windows 10
尼斯。没有解释的downvote。这非常没有生气。我怎么可能提供比我在这里更多的细节? –
'\ Readyshare \ ...'这正是路径?或者可能是'\\ Readyshare \ ...'文件不是本地的? – RbMm
路径从两条反斜杠开始,就像我在我的问题中那样。这是*确切的*路径。它在连接到我的路由器的USB驱动器上。直到我由于目录结构而开始获取这些较长的文件名时,我才有任何问题。 –