我在寫一個有錯誤的備份程序。用調試器遍歷代碼,我發現刪除文件時出現錯誤。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驅動器上。直到我由於目錄結構而開始獲取這些較長的文件名時,我纔有任何問題。 –