J'écris un programme de sauvegarde qui a des erreurs. En parcourant le code avec un débogueur, je constate que j'obtiens des erreurs en supprimant des fichiers.DeleteFile() échoue mais le fichier est là (nom de fichier très long)
J'utilise CFileFind
pour localiser les fichiers, et j'utilise CFileFind::GetFilePath()
pour obtenir le chemin d'accès complet.
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()
est de retour FALSE
et GetLastError()
est de retour 3 (ERROR_PATH_NOT_FOUND
), et est dans les autres cas de retour 2 (ERROR_FILE_NOT_FOUND
).
Comme vous pouvez le voir, je tente d'abord de supprimer l'attribut en lecture seule s'il est défini; cependant, je peux voir que le fichier existe et il n'a pas l'attribut en lecture seule.
Une chose à noter est que le nom du fichier est très long. Ce code a été testé et fonctionne plutôt bien avec des noms de fichiers plus courts. Dans ce cas, find.GetFilePath()
retours:
\\ readyshare \ USB 3 \ Backups \ DRIVEZ_BACKUP \ Stacey \ Backup 0001 \ Music \ SUPPRESS \ iTunes \ iTunes Media \ Musique \ Dave Matthews Band \ Loin du monde (version Deluxe) \ Loin du monde (Deluxe Version.itlp \ audio \ DaveMatthewsBand_AwayFromTheWorld_backgroundaudio.m4a
Et cela semble correct. Si je copie tous, mais le nom de fichier dans l'Explorateur Windows, il me montre ce dossier. Et la le fichier existe dans ce dossier
Est-ce que quelqu'un sait pourquoi DeleteFile()
me dirait que le chemin ou le fichier n'existe pas alors qu'en fait il le fait?
MISE À JOUR:
Sur la base de la réponse de Bruno Ferreira, je suis en cours d'exécution à travers mes noms de fichiers la méthode suivante. (Désolé pour l'ancien code de style CString, je suis mise à jour d'un programme MFC plus.)
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;
}
Comme vous pouvez le voir le code, prepends le préfixe approprié si le nom du fichier dépasse MAX_PATH
. Des mesures sont prises pour ajouter le préfixe approprié selon que le chemin spécifie ou non un chemin réseau.
Je ne sais pas pourquoi cela a été rendu incroyablement compliqué. Je ne vois vraiment pas de problème de compatibilité ascendante si Windows vous permet de spécifier un nom plus long. Sur Windows 10, il existe un paramètre de registre que vous pouvez modifier afin que cette absurdité ne soit pas requise. Mais bien sûr, je ne veux pas limiter mon logiciel aux versions de Windows ne peaufiné 10.
Nice. Une downvote sans explication. C'est plutôt moche. Comment pourrais-je fournir plus de détails que j'ai ici? –
'\ Readyshare \ ...' c'est exactement le chemin? ou peut être '\\ Readyshare \ ...' fichier pas local? – RbMm
Le chemin commence avec deux barres obliques inverses, comme je l'ai dans ma question. C'est le chemin * exact *. C'est sur une clé USB qui est connectée à mon routeur. Et je n'ai eu aucun problème jusqu'à ce que je commence à obtenir ces noms de fichiers plus longs en raison de la structure du répertoire. –