tamaño - ¿Por qué existe el límite de longitud de ruta de 260 caracteres en Windows?
habilitar rutas largas windows 7 (12)
Me he enfrentado a este problema varias veces en momentos inoportunos:
- tratando de trabajar en proyectos Java de código abierto con rutas profundas
- Almacenando árboles wiki de Fitnesse profundos en el control de código fuente
- Un error al intentar utilizar Bazaar para importar mi árbol de control de origen
¿Por qué existe este límite?
¿Por qué no se ha eliminado todavía?
¿Cómo hacer frente al límite de ruta? ... y no, cambiar a Linux o Mac OS X no es una respuesta válida a esta pregunta;)
Citando este artículo http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
Limitación máxima de longitud de trayectoria
En la API de Windows (con algunas excepciones analizadas en los párrafos siguientes), la longitud máxima de una ruta es MAX_PATH , que se define como 260 caracteres. Una ruta local está estructurada en el siguiente orden: letra de unidad, dos puntos, barra diagonal inversa, componentes de nombre separados por barras diagonales inversas y un carácter nulo de terminación. Por ejemplo, la ruta máxima en la unidad D es "D: / alguna cadena de ruta de 256 caracteres <NUL>" donde "<NUL>" representa el carácter nulo de terminación invisible para la página de códigos del sistema actual. (Los caracteres <> se utilizan aquí para mayor claridad visual y no pueden formar parte de una cadena de ruta válida).
Ahora vemos que es 1 + 2 + 256 + 1 o [unidad] [: /] [ruta] [null] = 260. Se podría suponer que 256 es una longitud de cadena fija razonable desde los días de DOS. Y volviendo a las API de DOS, nos damos cuenta de que el sistema rastreaba la ruta actual por unidad, y tenemos 26 unidades ( 32 con símbolos) con el máximo de unidades (y directorios actuales).
El INT 0x21 AH = 0x47 dice "Esta función devuelve la descripción de la ruta sin la letra de la unidad y la barra invertida inicial". Así que vemos que el sistema almacena la CWD como un par (unidad, ruta) y usted solicita la ruta especificando la unidad (1 = A, 2 = B,…), si especifica 0, asumirá la ruta de la unidad devuelta por INT 0x21 AH = 0x15 AL = 0x19. Así que ahora sabemos por qué es 260 y no 256, porque esos 4 bytes no están almacenados en la cadena de ruta.
Por qué una cadena de ruta de 256 bytes, porque 640K es suficiente RAM.
Desde Windows 10. puede eliminar la limitación modificando una clave de registro.
Sugerencia A partir de Windows 10, versión 1607, las limitaciones de MAX_PATH se han eliminado de las funciones comunes de archivos y directorios de Win32. Sin embargo, debe optar por el nuevo comportamiento.
Una clave de registro le permite habilitar o deshabilitar el nuevo comportamiento de ruta larga. Para habilitar el comportamiento de ruta larga, establezca la clave de registro en
HKLM/SYSTEM/CurrentControlSet/Control/FileSystem LongPathsEnabled
(Type:REG_DWORD
). El sistema almacenará en caché el valor de la clave (por proceso) después de la primera llamada a un archivo Win32 afectado o función de directorio (la lista sigue). La clave de registro no se volverá a cargar durante la vida útil del proceso. Para que todas las aplicaciones en el sistema reconozcan el valor de la clave, puede ser necesario reiniciar porque algunos procesos pueden haberse iniciado antes de que se configurara la clave. La clave de registro también se puede controlar a través de la Política de grupo enComputer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths
. También puede habilitar el nuevo comportamiento de ruta larga por aplicación a través del manifiesto:
<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>
En cuanto a por qué esto todavía existe, MS no lo considera una prioridad y valora la compatibilidad con versiones anteriores sobre el avance de su sistema operativo (al menos en esta instancia).
Una solución alternativa que utilizo es usar los "nombres cortos" para los directorios en la ruta, en lugar de sus versiones estándar, legibles por humanos. Entonces, por ejemplo, para C:/Program Files/
usaría C:/PROGRA~1/
Puede encontrar los equivalentes de nombre corto usando dir /x
.
En cuanto a cómo hacer frente a la limitación del tamaño de la ruta en Windows, usar 7zip para empaquetar (y desempaquetar) sus archivos sensibles a la longitud de la ruta parece una solución viable. Lo he usado para transportar varias instalaciones IDE (esas rutas de complementos de Eclipse, ¡ay!) Y montones de documentación generada automáticamente y no he tenido un solo problema hasta ahora.
No estoy realmente seguro de cómo evade el límite de 260 caracteres establecido por Windows (desde un punto de vista técnico), pero ¡hey, funciona!
Más detalles en su página de SourceForge here :
"NTFS puede admitir rutas de hasta 32,000 caracteres de longitud".
7-zip también soporta nombres tan largos.
Pero está deshabilitado en el código SFX. A algunos usuarios no les gustan los caminos largos, ya que no entienden cómo trabajar con ellos. Es por eso que lo he deshabilitado en código SFX.
9.32 alfa 2013-12-01
- Compatibilidad mejorada para rutas de archivos de más de 260 caracteres.
4.44 beta 2007-01-20
- 7-Zip ahora admite rutas de archivos con más de 260 caracteres.
NOTA IMPORTANTE: para que esto funcione correctamente, deberá especificar la ruta de destino en el cuadro de diálogo "Extraer" de 7zip directamente, en lugar de arrastrar y soltar los archivos en la carpeta deseada. De lo contrario, la carpeta "Temp" se usará como caché provisional y rebotará en la misma limitación de 260 caracteres una vez que Windows Explorer comience a mover los archivos a su "lugar de descanso final". Ver las respuestas a esta pregunta para más información.
La pregunta es por qué la limitación sigue existiendo. Seguramente Windows moderno puede aumentar el lado de MAX_PATH
para permitir rutas más largas. ¿Por qué no se ha eliminado la limitación?
- La razón por la que no se puede eliminar es que Windows prometió que nunca cambiaría.
A través del contrato de API, Windows ha garantizado a todas las aplicaciones que las API de archivos estándar nunca devolverán una ruta de más de 260
caracteres.
Considere el siguiente código correcto :
WIN32_FIND_DATA findData;
FindFileFirst("C:/Contoso/*", ref findData);
Windows garantizó a mi programa que WIN32_FIND_DATA
mi estructura WIN32_FIND_DATA
:
WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
//...
TCHAR cFileName[MAX_PATH];
//..
}
Mi aplicación no declaró el valor de la constante MAX_PATH
, lo hizo la API de Windows. Mi aplicación usó ese valor definido.
Mi estructura está correctamente definida y solo asigna 592
bytes en total. Eso significa que solo puedo recibir un nombre de archivo que tenga menos de 260
caracteres. Windows me prometió que si escribía mi aplicación correctamente, mi aplicación continuaría funcionando en el futuro.
Si Windows permitiera nombres de archivo de más de 260
caracteres, mi aplicación existente (que usaba la API correcta correctamente) fallaría.
Para cualquiera que llame a Microsoft para cambiar la constante MAX_PATH
, primero deben asegurarse de que no se MAX_PATH
un error en la aplicación existente. Por ejemplo, todavía poseo y uso una aplicación de Windows que fue escrita para ejecutarse en Windows 3.11. Todavía se ejecuta en Windows 10 de 64 bits. Eso es lo que te ofrece la compatibilidad con versiones anteriores.
Microsoft creó una forma de usar los 32,768 nombres de ruta completos; pero tenían que crear un nuevo contrato de API para hacerlo. Por un lado, debe usar la API de Shell para enumerar archivos (ya que no todos los archivos existen en un disco duro o recurso compartido de red).
Pero también tienen que no romper las aplicaciones de usuario existentes. La gran mayoría de las aplicaciones no utilizan la api de shell para el trabajo de archivos. Todos simplemente llaman a FindFirstFile
/ FindNextFile
y lo llaman un día.
Lo hace, y es un valor predeterminado por algún motivo, pero podría anularlo fácilmente con esta clave de registro:
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/FileSystem] "LongPathsEnabled"=dword:00000001
Consulte: https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/
Mientras todos lloran que 260 caracteres son horribles en 2017, de alguna manera nadie dice que la mayoría de gnu shitware se rompe si encuentra espacios en los caminos. Ni siquiera unicode. Y hablando de funciones intrínsecamente rotas, piensa en tu strcpy
favorita sin la n
. Incluso malloc
está roto en Linux porque se basa en fallas de página para confirmar el espacio de direcciones reservado (que es lento y propenso a errores). Nadie es perfecto, y la ignorancia no es una razón válida para lloriquear.
Además, los comentaristas de alguna manera no dicen qué es exactamente lo que está roto.
Hay 3 cosas que están rotas:
ciertas llamadas (solo conozco Get / SetCurrentDirectoryW) están limitadas a un solo hilo y 260 caracteres sin importar qué. Así que, esencialmente, las rutas relativas se rompen en Windows, emúlalas como si fueras emular
fork
si te obligas a hacerlo.el software portado desde no ventanas que se basa intrínsecamente en conceptos que no son ventanas (incluido el concepto de las rutas dir / relativas actuales, ver más arriba)
El software está escrito desde cero para Windows, pero aún usa una API antigua (pero vea más arriba, aunque existen API para el acceso general al sistema de archivos, no hay una API para el directorio actual en Windows que funciona más allá de MAX_PATH)
En cuanto a por qué todavía está roto, en mi opinión, MS solucionó todo lo que se puede arreglar. Creo que es la herencia del directorio actual por procesos secundarios que no permite que GetCurrentDirectoryW sea reparado.
Otra forma de enfrentarlo es usar Cygwin, dependiendo de lo que quieras hacer con los archivos (es decir, si los comandos de Cygwin se adaptan a tus necesidades)
Por ejemplo, permite copiar, mover o renombrar archivos que incluso el Explorador de Windows no puede. O por supuesto tratar con los contenidos de ellos como md5sum, grep, gzip, etc.
También para los programas que estás codificando, podrías vincularlos a la DLL de Cygwin y les permitiría usar rutas largas (aunque no he probado esto)
Puede habilitar nombres de ruta largos usando PowerShell:
Set-ItemProperty -Path ''HKLM:/SYSTEM/CurrentControlSet/Control/FileSystem'' -Name LongPathsEnabled -Type DWord -Value 1
Otra versión es usar una Política de grupo en Computer Configuration
/ Administrative Templates
/ System
/ System
Filesystem
:
Puede montar una carpeta como un disco. Desde la línea de comandos, si tiene una ruta C:/path/to/long/folder
, puede asignarla a la unidad X:
usando:
subst x: /path/to/long/folder
Una forma de hacer frente al límite de ruta es acortar las entradas de ruta con enlaces simbólicos.
Por ejemplo:
- cree un directorio
C:/p
para mantener enlaces cortos a rutas largas -
mklink /JC:/p/foo C:/Some/Crazy/Long/Path/foo
- agrega
C:/p/foo
a tu ruta en lugar de la ruta larga
Esto no es estrictamente cierto ya que el sistema de archivos NTFS admite rutas de hasta 32k caracteres. Puede usar la api de win32 y el prefijo " //?/
" En la ruta para usar más de 260 caracteres.
Una explicación detallada del largo camino desde el blog del equipo .Net BCL .
Un pequeño extracto destaca el tema con largos caminos.
Otra preocupación es el comportamiento inconsistente que resultaría al exponer el soporte de camino largo. Las rutas largas con el prefijo
//?/
Se pueden usar en la mayoría de las API de Windows relacionadas con archivos, pero no en todas las API de Windows. Por ejemplo, LoadLibrary, que asigna un módulo a la dirección del proceso de llamada, falla si el nombre del archivo es más largo que MAX_PATH. Entonces, esto significa que MoveFile le permitirá mover una DLL a una ubicación tal que su ruta tenga más de 260 caracteres, pero cuando intente cargar la DLL, fallará. Hay ejemplos similares en todas las API de Windows; Existen algunas soluciones alternativas, pero se realizan caso por caso.