¿Qué caracteres están prohibidos en los nombres de directorio de Windows y Linux?

Sé que / es ilegal en Linux, y los siguientes son ilegales en Windows (creo) * . " / \ [ ] ; | = ,

¿Qué más me estoy perdiendo?

Sin embargo, necesito una guía completa y una que tenga en cuenta los caracteres de doble byte. Vincularme a recursos externos está bien para mí.

Primero necesito crear un directorio en el sistema de archivos usando un nombre que pueda contener caracteres prohibidos, así que planeo reemplazar esos caracteres con guiones bajos. Entonces necesito escribir este directorio y su contenido en un archivo zip (usando Java), por lo que cualquier consejo adicional sobre los nombres de los directorios zip sería apreciado.

Una “guía completa” de caracteres de nombre de archivo prohibidos no funcionará en Windows porque reserva los nombres de archivo y los caracteres. Sí, los caracteres como * " ? Y otros están prohibidos, pero hay un número infinito de nombres compuestos únicamente por caracteres válidos que están prohibidos. Por ejemplo, los espacios y los puntos son caracteres de nombre de archivo válidos, pero los nombres compuestos solo por esos caracteres están prohibidos.

Windows no distingue entre caracteres en mayúscula y minúscula, por lo que no puede crear una carpeta llamada A si ya existe una llamada a . Peor aún, nombres aparentemente permitidos como PRN y CON , y muchos otros, están reservados y no permitidos. Windows también tiene varias restricciones de longitud; un nombre de archivo válido en una carpeta puede dejar de ser válido si se mueve a otra carpeta. Las reglas para nombrar archivos y carpetas están en MSDN.

No puede, en general, usar texto generado por el usuario para crear nombres de directorio de Windows. Si desea permitir que los usuarios nombren lo que quieran, debe crear nombres seguros como A , AB , A2 y otros, almacenar los nombres generados por el usuario y sus equivalentes de ruta en un archivo de datos de la aplicación y realizar la asignación de ruta en su aplicación .

Si debe permitir absolutamente los nombres de carpeta generados por el usuario, la única forma de saber si son inválidos es detectar excepciones y asumir que el nombre no es válido. Incluso eso está plagado de peligros, ya que las excepciones generadas para el acceso denegado, las unidades fuera de línea y el espacio fuera de la unidad se superponen con aquellas que pueden arrojarse por nombres inválidos. Estás abriendo una enorme lata de dolor.

Vamos a mantenerlo simple y responder la pregunta, primero.

  1. Los caracteres ASCII imprimibles prohibidos son:

    • Linux / Unix:

       / (forward slash) 
    • Windows:

       < (less than) > (greater than) : (colon - sometimes works, but is actually NTFS Alternate Data Streams) " (double quote) / (forward slash) \ (backslash) | (vertical bar or pipe) ? (question mark) * (asterisk) 
  2. Caracteres no imprimibles

    Si sus datos provienen de una fuente que permitiría caracteres no imprimibles, entonces hay más que verificar.

    • Linux / Unix:

       0 (NULL byte) 
    • Windows:

       0-31 (ASCII control characters) 

    Nota: Si bien es legal en los sistemas de archivos Linux / Unix crear archivos con caracteres de control en el nombre del archivo, puede ser una pesadilla para los usuarios tratar con dichos archivos .

  3. Nombres de archivos reservados

    Los siguientes nombres de archivos están reservados:

    • Windows:

       CON, PRN, AUX, NUL COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9 LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 
  4. Otras reglas

    • Windows:

      Los nombres de archivo no pueden terminar en un espacio o punto.

En Linux y otros sistemas relacionados con Unix, solo hay dos caracteres que no pueden aparecer en el nombre de un archivo o directorio, y esos son NUL '\0' y slash '/' . La barra inclinada, por supuesto, puede aparecer en un nombre de ruta, separando los componentes del directorio.

Rumor 1 dice que Steven Bourne (de la fama de ‘shell’) tenía un directorio que contenía 254 archivos, uno por cada letra (código de carácter) que puede aparecer en un nombre de archivo (excluyendo / , '\0' ; el nombre era el directorio actual, por supuesto). Se usó para probar el shell Bourne y ocasionó esgulps rutinariamente en progtwigs incautos como los progtwigs de copia de seguridad.

Otras personas han cubierto las reglas de Windows.

Tenga en cuenta que MacOS X tiene un sistema de archivos insensible a mayúsculas y minúsculas.


1 Fue Kernighan & Pike en The Practice of Programming quien dijo tanto en el Capítulo 6, Pruebas, §6.5 Pruebas de estrés:

Cuando Steve Bourne estaba escribiendo su shell de Unix (que se conocía como el shell de Bourne), creó un directorio de 254 archivos con nombres de un solo carácter, uno para cada valor de byte excepto '\0' y barra, los dos caracteres que no puede aparecer en los nombres de archivo de Unix. Utilizó ese directorio para todo tipo de pruebas de coincidencia de patrones y tokenización. (El directorio de prueba fue, por supuesto, creado por un progtwig.) Durante años después, ese directorio fue la perdición de los progtwigs de búsqueda de árboles de archivos; los probó a la destrucción.

En lugar de crear una lista negra de caracteres, puede usar una lista blanca . Considerando todo, el rango de caracteres que tienen sentido en un contexto de nombre de archivo o directorio es bastante corto, y a menos que tenga algunos requisitos de nombres muy específicos, sus usuarios no lo retendrán en contra de su aplicación si no pueden usar toda la tabla ASCII.

No resuelve el problema de los nombres reservados en el sistema de archivos de destino, pero con una lista blanca es más fácil mitigar los riesgos en la fuente.

En ese espíritu, esta es una gama de personajes que pueden considerarse seguros:

  • Cartas (az AZ) – Caracteres Unicode también, si es necesario
  • Dígitos (0-9)
  • Guion bajo (_)
  • Guión (-)
  • Espacio
  • Punto (.)

Y cualquier carácter seguro adicional que desee permitir. Más allá de esto, solo tienes que aplicar algunas reglas adicionales con respecto a espacios y puntos . Esto usualmente es suficiente:

  • El nombre debe contener al menos una letra o número (para evitar solo puntos / espacios)
  • El nombre debe comenzar con una letra o número (para evitar puntos / espacios iniciales)

Esto ya permite nombres bastante complejos y sin sentido. Por ejemplo, estos nombres serían posibles con estas reglas y serían nombres de archivo válidos en Windows / Linux:

  • A...........ext
  • B -.- .ext

Básicamente, incluso con tan pocos personajes en la lista blanca, debe decidir lo que realmente tiene sentido y validar / ajustar el nombre en consecuencia. En una de mis aplicaciones, utilicé las mismas reglas que las anteriores pero eliminé los puntos y espacios duplicados.

Bueno, aunque solo sea con fines de investigación, entonces la mejor opción es mirar esta entrada de Wikipedia en Nombre de archivo .

Si desea escribir una función portátil para validar la entrada del usuario y crear nombres de archivo basados ​​en eso, la respuesta corta es “no” . Eche un vistazo a un módulo portátil como Perl’s File :: Spec para echar un vistazo a todos los saltos necesarios para lograr una tarea tan “simple”.

La manera fácil de hacer que Windows le diga la respuesta es intentar cambiar el nombre de un archivo a través de Explorer y escribir / para el nuevo nombre. Windows mostrará un cuadro de mensaje que le indicará la lista de caracteres ilegales.

 A filename cannot contain any of the following characters: \ / : * ? " < > | 

https://support.microsoft.com/en-us/kb/177506

Para Windows, puede verificarlo con PowerShell

 $PathInvalidChars = [System.IO.Path]::GetInvalidPathChars() #36 chars 

Para mostrar los códigos UTF-8 puede convertir

 $enc = [system.Text.Encoding]::UTF8 $PathInvalidChars | foreach { $enc.GetBytes($_) } $FileNameInvalidChars = [System.IO.Path]::GetInvalidFileNameChars() #41 chars $FileOnlyInvalidChars = @(':', '*', '?', '\', '/') #5 chars - as a difference 

A partir del 18/04/2017, no hay una lista simple en blanco o negro de caracteres y nombres de archivos entre las respuestas a este tema, y ​​hay muchas respuestas.

La mejor sugerencia que se me ocurrió fue dejar que el usuario nombrara el archivo como quisiera. Usando un controlador de errores cuando la aplicación intenta guardar el archivo, capture cualquier excepción, suponga que el nombre de archivo es el culpable (obviamente después de asegurarse de que la ruta de guardado también estuvo bien), y solicite al usuario un nuevo nombre de archivo. Para obtener los mejores resultados, coloque este procedimiento de verificación dentro de un ciclo que continúe hasta que el usuario lo haga bien o se dé por vencido. Funcionó mejor para mí (al menos en VBA).

Ejemplo de código VBA: (se agregará más tarde)

Aunque los únicos caracteres ilegales de Unix pueden ser / y NULL , aunque se debe incluir alguna consideración para la interpretación de la línea de comandos.

Por ejemplo, aunque podría ser legal nombrar un archivo 1>&2 o 2>&1 en Unix, los nombres de archivo como este podrían malinterpretarse cuando se usan en una línea de comando.

De manera similar, podría ser posible nombrar un archivo $PATH , pero cuando intente acceder a él desde la línea de comando, el shell traducirá $PATH a su valor de variable.

Al crear accesos directos a Internet en Windows, para crear el nombre de archivo, omite caracteres ilegales, excepto la barra diagonal, que se convierte en menos.

En los shells de Unix, puedes citar casi todos los caracteres en comillas simples ' . Excepto la comilla simple misma, y ​​no puede express los caracteres de control, porque \ no está expandido. Es posible acceder a la comilla simple desde una cadena entrecomillada, ya que puede concatenar cadenas con comillas simples y dobles, como 'I'"'"'m' que se puede usar para acceder a un archivo llamado "I'm" (doble cita también posible aquí).

Por lo tanto, debe evitar todos los caracteres de control, ya que son demasiado difíciles de ingresar en el shell. El rest sigue siendo divertido, especialmente los archivos que comienzan con un guion, porque la mayoría de los comandos los lee como opciones a menos que tenga dos guiones antes, o los especifique con ./ , que también oculta el inicio - .

Si quieres ser agradable, no uses ninguno de los caracteres que el shell y los comandos típicos usan como elementos sintácticos, a veces depende de la posición, por ejemplo, todavía puedes usar - , pero no como primer carácter; lo mismo con . , puede usarlo como primer carácter solo cuando lo dice en serio (“archivo oculto”). Cuando eres malo, tus nombres de archivo son secuencias de escape VT100 ;-), de modo que un ls deshabilita la salida.

Tenía la misma necesidad y estaba buscando recomendaciones o referencias estándar y encontré este hilo. Mi lista negra actual de caracteres que deben evitarse en nombres de archivos y directorios es:

 $CharactersInvalidForFileName = { "pound" -> "#", "left angle bracket" -> "<", "dollar sign" -> "$", "plus sign" -> "+", "percent" -> "%", "right angle bracket" -> ">", "exclamation point" -> "!", "backtick" -> "`", "ampersand" -> "&", "asterisk" -> "*", "single quotes" -> "“", "pipe" -> "|", "left bracket" -> "{", "question mark" -> "?", "double quotes" -> "”", "equal sign" -> "=", "right bracket" -> "}", "forward slash" -> "/", "colon" -> ":", "back slash" -> "\\", "lank spaces" -> "b", "at sign" -> "@" };