Pourquoi la limite de longueur de chemin de 260 caractères existe-t-elle dans Windows?
j'ai rencontré ce problème à plusieurs reprises à des moments inopportuns:
- essayer de travailler sur l'open source Java de projets avec une profonde chemins
- stockage des wiki Deep Fitnesse dans le contrôle à la source
- une erreur en essayant d'utiliser Bazaar pour importer mon arbre de contrôle source
Pourquoi cette limite existe pas?
pourquoi n'a-t-il pas encore été enlevé?
comment supportez-vous la limite du chemin? ... et non, le passage à linux ou Mac OS X n'est pas une réponse valable à cette question ;)
12 réponses
citant cet article http://msdn.microsoft.com/en-us/library/aa365247 (VS.85).aspx # maxpath
Limitation De La Longueur Maximale Du Trajet
dans L'API Windows (avec quelques exceptions discutées dans les paragraphes suivants), la longueur maximale d'un chemin est MAX_PATH , qui est défini comme 260 caractères. Un chemin local est structuré dans l'ordre suivant:: lettre de lecteur, du côlon, de la barre oblique inverse, le nom des composants séparés par des barres obliques inverses, et un caractère de fin null. Par exemple, le chemin maximum sur le disque D est "D:\ quelque chaîne de chemin de 256 caractères
" où " " représente le caractère invisible terminal nul pour la page de code du système actuel. (Les caractères < > sont utilisés ici pour la clarté visuelle et ne peuvent pas faire partie d'une chaîne de chemin valide.)
Maintenant, nous voyons qu'il est 1+2+256+1 ou [lecteur][:\][chemin][null] = 260. On pourrait supposer que 256 est une longueur de chaîne fixe raisonnable à partir des jours DOS. Et en revenant à L'API DOS nous réalisons que le système a suivi le chemin actuel par lecteur, et nous avons 26 (32 avec des symboles) lecteurs maximum (et répertoires courants).
L'INT 0x21 AH=0x47 dit "Cette fonction renvoie la description du chemin sans la lettre du lecteur et le antislash initial."Nous voyons donc que le système stocke L'ECD comme une paire (lecteur, chemin) et vous demandez le chemin en spécifiant le lecteur (1=a, 2=B,...), Si vous spécifiez un 0 alors il assume le chemin pour le lecteur retourné par INT 0x21 AH=0x15 AL=0x19. Donc maintenant nous savons pourquoi c'est 260 et pas 256, parce que ces 4 octets ne sont pas stockés dans la chaîne de chemin.
Pourquoi une 256 octets chaîne de chemin, parce que 640 KO de suffisamment de mémoire RAM.
ce n'est pas strictement vrai car le système de fichiers NTFS supporte des chemins allant jusqu'à 32k caractères. Vous pouvez utiliser l'api win32 et le préfixe " \?\
" du chemin pour utiliser plus de 260 caractères.
Une explication détaillée de long chemin de l' .Net BCL blog de l'équipe .
Un petit extrait met en évidence la question avec de longs chemins
une autre préoccupation est un comportement incohérent qui résultat en exposant le support long path. Les longs chemins avec le préfixe
\?\
peuvent être utilisés dans la plupart des API Windows liées aux fichiers, mais pas dans toutes les API Windows. Par exemple, LoadLibrary, qui établit une correspondance entre un module et l'adresse du processus d'appel, échoue si le nom du fichier est plus long que MAX_PATH. Cela signifie donc que MoveFile vous permettra de déplacer une DLL à un endroit tel que son chemin est plus long que 260 caractères, mais lorsque vous essayez de charger la DLL, il échouerait. Il existe des exemples similaires dans l'ensemble de la APIs Windows; certaines solutions de rechange existent, mais elles sont au cas par cas.
La question est pourquoi la limitation existent encore. Sûrement les fenêtres modernes peuvent augmenter le côté de MAX_PATH
pour permettre des chemins plus longs. Pourquoi la limitation n'a été supprimé?
- la raison pour laquelle il ne peut pas être enlevé est que Windows a promis qu'il ne changerait jamais.
grâce à un contrat API, Windows a garanti à toutes les applications que les API fichiers standards ne retourneront jamais un chemin plus long que les caractères 260
.
considérer le suivant corriger code:
WIN32_FIND_DATA findData;
FindFileFirst("C:\Contoso\*", ref findData);
Windows garanti mon programme qu'il remplirait ma WIN32_FIND_DATA
structure:
WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
//...
TCHAR cFileName[MAX_PATH];
//..
}
mon application n'a pas déclaré la valeur de la constante MAX_PATH
, L'API de Windows l'a fait. Mon application utilisait cette valeur définie.
My la structure est correctement définie, et n'affecte que 592
bytes total. Cela signifie que je ne peux recevoir qu'un nom de fichier inférieur aux caractères 260
. Windows a promis moi que si j'écrivais mon application correctement, mon application continuerait à fonctionner à l'avenir.
si Windows permettait des noms de fichiers plus longs que 260
, alors mon application existante (qui utilisait correctement L'API correcte) échouer.
pour quiconque demande à Microsoft de changer la constante MAX_PATH
, ils doivent d'abord s'assurer qu'aucune application existante ne échoue. Par exemple, je possède et utilise toujours une application Windows qui a été écrite pour fonctionner sur Windows 3.11. Il fonctionne toujours sous Windows 10 64 bits. C'est ce que la rétrocompatibilité vous apporte.
Microsoft did créer une façon d'utiliser les 32 768 noms de chemin complets; mais ils ont dû créer une nouvelle API contrat à le faire. Pour un, vous devez utiliser le API Shell pour énumérer les fichiers (comme tous les fichiers n'existent pas sur un disque dur ou un partage réseau).
mais ils ne doivent pas non plus briser les applications utilisateurs existantes. La grande majorité des applications ne pas utilisent l'api shell pour le travail de fichier. Tout le monde appelle FindFirstFile
/ FindNextFile
et appelle ça un jour.
De Windows 10. vous pouvez supprimer la restriction en modifiant une clé de registre.
Tip depuis Windows 10, version 1607, les limitations de MAX_PATH ont été retirées des fonctions courantes de fichiers Win32 et de répertoires. Cependant, vous devez opter pour le nouveau comportement.
une clé de registre vous permet d'activer ou de désactiver le nouveau comportement long path. Pour activer le comportement de long path définissez la clé de Registre à
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled
(Type:REG_DWORD
). La valeur de la clé sera mise en cache par le système (par processus) après le premier appel à un fichier Win32 affecté ou à une fonction de répertoire (la liste suit). La clé de registre ne sera pas rechargé pendant la durée du processus. Pour que toutes les applications du système reconnaissent la valeur de la clé, un redémarrage peut être nécessaire parce que certains processus peuvent avoir commencé avant que la clé ne soit définie. La clé de registre peut également être contrôlé par le Groupe Politique auComputer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths
. Vous pouvez également activer le nouveau comportement long path par app via le manifeste:<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
vous pouvez monter un dossier comme un lecteur. À partir de la ligne de commande, si vous avez un chemin C:\path\to\long\folder
, vous pouvez le mapper pour conduire la lettre X:
en utilisant:
subst x: \path\to\long\folder
une façon de gérer la limite de chemin est de raccourcir les entrées de chemin avec des liens symboliques.
par exemple:
- créer un
C:\p
répertoire pour garder les liens courts aux longs chemins -
mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
- ajouter
C:\p\foo
à votre chemin au lieu du long
comme pourquoi cela existe encore - MS ne considère pas cela comme une priorité, et évalue la compatibilité ascendante par rapport à la progression de son OS (au moins dans ce cas).
une solution que j'utilise est d'utiliser les" noms courts " pour les répertoires dans le chemin, au lieu de leurs versions standard lisibles par l'utilisateur. Ainsi par exemple pour C:\Program Files\
j'utiliserais C:\PROGRA~1\
vous pouvez trouver les équivalents de nom court en utilisant dir /x
.
quant à la façon de faire face à la limitation de la taille du chemin D'accès sur Windows - en utilisant 7zip pour empaqueter (et déballer) vos fichiers sensibles à la longueur du chemin semble comme une solution de contournement viable. Je l'ai utilisé pour transporter plusieurs installations IDE (ces chemins de plugin Eclipse, Beurk!) et des piles de documentation autogénérée et n'ont pas eu un seul problème jusqu'à présent.
pas vraiment sûr comment il échappe à la limite de 260 char fixé par Windows (à partir d'un PoV technique), mais bon, il œuvres!
plus de détails sur leur page SourceForge ici :
" NTFS peut effectivement prendre en charge les noms de chemin jusqu'à 32.000 caractères longueur."
7-zip supporte aussi des noms aussi longs.
mais il est désactivé en code SFX. Certains utilisateurs n'aiment pas les longs chemins, depuis ils ne comprennent pas comment travailler avec eux. C'est pourquoi j'ai désactivé en code SFX.
et notes de mise à jour :
9,32 alpha 2013-12-01
- support amélioré pour les noms de chemin de fichier de plus de 260 caractères.
4.44 bêta 2007-01-20
- 7-Zip supporte maintenant les noms de fichier de plus de 260 caractères.
NOTE IMPORTANTE: pour que cela fonctionne correctement, vous aurez besoin de spécifier le chemin de destination dans la boîte de dialogue 7zip " extraire " directement, plutôt que de glisser et déposer les fichiers dans le dossier prévu. Sinon, le dossier" Temp "sera utilisé comme cache provisoire et vous rebondirez dans la même limite de 260 char lorsque Windows Explorer commencera à déplacer les fichiers vers leur"lieu de repos final". Voir les réponses à cette question pour plus d'informations.
une autre façon d'y faire face est D'utiliser Cygwin, en fonction de ce que vous voulez faire avec les fichiers (i.e. si les commandes Cygwin conviennent à vos besoins)
par exemple, il permet de copier, déplacer ou renommer des fichiers que même Windows Explorer ne peut pas. Ou bien sûr traiter le contenu d'entre eux comme md5sum, grep, gzip, etc.
aussi pour les programmes que vous codez, vous pouvez les lier à la DLL Cygwin et il leur permettrait d'utiliser de longs chemins (Je n'ai pas testé cela cependant)
il le fait, et il est un défaut pour une raison quelconque, mais vous pourriez facilement l'outrepasser avec cette clé de registre:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
voir: https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10 /
vous pouvez activer les noms de chemins longs en utilisant PowerShell:
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1
une autre Version est d'utiliser une politique de groupe dans Computer Configuration
/ Administrative Templates
/ System
/ Filesystem
:
alors que tout le monde pleure que les 260 chars sont horribles en 2017, personne ne pleure que la plupart des shitware gnu se cassent s'ils rencontrent des espaces dans les chemins. Pas même unicode. Et en parlant de fonctions intrinsèquement brisées-pensez à votre favori strcpy
sans le n
. Même malloc
est cassé sur linux parce qu'il s'appuie sur des défauts de page pour réellement propager l'espace d'adresse réservé (qui est lent et sujet aux bogues). Personne n'est parfait, et l'ignorance n'est pas une raison valable pour se lamenter.
aussi, les commentateurs ne disent pas ce qui est cassé exactement.
il y a 3 choses qui sont brisées:
-
certains appels (Je suis seulement au courant de Get/SetCurrentDirectoryW) sont limités à un seul thread et 260 caractères peu importe quoi. Donc les chemins essentiellement relatifs sont cassés sur les fenêtres, émulez - les tout comme vous émulez
fork
si vous êtes forcé. -
le logiciel porté de non-windows qui repose de manière inhérente sur des concepts non-windows (y compris le concept de dir/relative chemins actuels, voir ci-dessus)
-
le logiciel qui est écrit à partir de zéro pour Windows, mais utilise toujours une ancienne API (mais voir ci - dessus-alors qu'il y a des API pour l'accès général au système de fichiers, il n'y a pas D'API pour le répertoire courant sur Windows qui fonctionne après MAX_PATH)
1519140920"
quant à la raison pour laquelle il est encore cassé - à mon avis MS corrigé tout ce qui est réparable. Je pense que c'est l'héritage du répertoire courant par les processus enfants qui ne permet pas de corriger GetCurrentDirectoryW.