Я пишу программу резервного копирования с ошибками. Поступая через код с помощью отладчика, я обнаруживаю, что получаю ошибки при удалении файлов.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 \ Stacey \ Backup 0001 \ Music \ TO УДАЛИТЬ \ ITunes \ ITunes Медиа \ Музыка \ Dave Matthews Band \ Вдали от мира (Deluxe Version) \ Вдали от World (Deluxe Version.itlp \ аудио \ DaveMatthewsBand_AwayFromTheWorld_backgroundaudio.m4a
И это выглядит правильно. Если я копирую все, но имя файла в Windows Explorer, он показывает мне эту папку. И файл существует в этой папке.
Кто-нибудь знает почему 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.
Nice. Сдвиг без объяснения. Это довольно бесхарактерно. Как я могу предоставить более подробную информацию, чем здесь? –
'\ Readyshare \ ...' это точно путь? или может быть '\\ Readyshare \ ...' файл не локальным? – RbMm
Путь начинается с двух обратных косых черт, как у меня в моем вопросе. Это * точный * путь. Это на USB-накопителе, подключенном к моему маршрутизатору. И у меня не было никаких проблем, пока я не начал получать эти более длинные имена файлов из-за структуры каталогов. –