107 votes

Comment traiter les fichiers dont le nom comporte plus de 259 caractères ?

Je travaille sur une application qui parcourt tous les fichiers de certains répertoires et effectue des actions sur ces fichiers. Entre autres, je dois récupérer la taille du fichier et la date à laquelle ce fichier a été modifié.

Certains noms complets de fichiers (répertoire + nom de fichier) étant trop longs, je n'ai pas pu utiliser le .NET Framework. FileInfo qui se limite à MAX_PATH (260 caractères). De nombreuses sources web conseillent d'utiliser les fonctions natives Win32 via P/Invoke pour accéder aux fichiers dont les noms sont trop longs.

Actuellement, le même problème semble se poser avec les fonctions Win32. Par exemple, GetFileAttributesEx (kernel32.dll) échoue avec l'erreur Win32 3 ERROR_PATH_NOT_FOUND pour le chemin de 270 octets.

Le même fichier peut être ouvert avec succès à partir du Bloc-notes2 et affiché avec succès avec l'Explorateur Windows (mais Visual Studio 2010, par exemple, ne parvient pas à l'ouvrir en raison de la limite de 259 caractères¹).

Que puis-je faire pour pouvoir accéder à un fichier lorsque le chemin d'accès est long de 270 caractères ?

Notes :

  • Supprimer ou ignorer les fichiers dont le chemin d'accès comporte plus de 259 caractères n'est pas une solution.

  • Je recherche uniquement des solutions compatibles avec Unicode.

  • L'application fonctionnera sous Windows 2008/Vista ou une version ultérieure avec .NET Framework 4 installé.


¹ Étonnamment, Microsoft Word 2007 échoue, se plaignant que "la disquette est trop petite" sur un ordinateur qui n'a pas de lecteur de disquette, ou que "la mémoire RAM est faible" alors qu'il reste 4 Go de RAM, ou enfin que "le logiciel antivirus [...] doit être mis à jour". Cesseront-ils un jour d'afficher des erreurs aussi stupides et dénuées de sens, au moins dans des produits aussi essentiels que Microsoft Office ?

5voto

Sakthi Vel C Points 21

Veuillez mettre à jour votre fichier de configuration comme suit :

<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
  </runtime>
</configuration>

3voto

Shane Lu Points 590

Pour un dossier partagé ( \\ServerName\PathThatIsVeryLong\ ), nous pourrions utiliser " \\ ? \UNC\ServerName\PathThatIsVeryLong\ "où "ServerName" est le nom de l'ordinateur et "PathThatIsVeryLong" est le nom du dossier partagé.

Référencement : https://learn.microsoft.com/en-us/Windows/win32/fileio/naming-a-file?redirectedfrom=MSDN

2voto

lunixbochs Points 7475

En Référence MSDN pour GetFileAttributesEx dit :

Dans la version ANSI de cette fonction, le nom est limité à MAX_PATH caractères. Pour étendre cette limite à 32 767 caractères, appelez la version Unicode de la fonction et ajoutez " \\ ?\" au chemin d'accès. Pour plus d'informations, voir Nommer un fichier .

Vous devez donc utiliser GetFileAttributesExW et préfixer votre chemin d'accès par " \\ ?\"

0voto

Oskar Henriksson Points 184

La création d'un processus distinct qui utilise Robocopy est également une solution, comme indiqué ici : Comment déplacer des dossiers/fichiers avec des noms de chemin > 255 caractères dans Windows 8.1 ?

  public static void RoboCopy(string src, string dst)
        {
            Process p = new Process();
            p.StartInfo.Arguments = string.Format("/C Robocopy {0} {1}", src, dst);
            p.StartInfo.FileName = "CMD.EXE";
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.Start();
            p.WaitForExit();
        }

Comme on l'a vu dans : Copie de fichiers à l'aide de robo copy et process

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X