Quais caracteres são proibidos nos nomes de diretório do Windows e Linux?

Eu sei que / é ilegal no Linux, e os seguintes são ilegais no Windows (eu acho) * . " / \ [ ] ; | = ,

O que mais eu estou sentindo falta?

Eu preciso de um guia abrangente, no entanto, e um que leva em conta os caracteres de byte duplo. Vincular a resources externos é bom para mim.

Eu preciso primeiro criar um diretório no sistema de arquivos usando um nome que pode conter caracteres proibidos, então eu pretendo replace esses caracteres com sublinhados. Eu então preciso escrever este diretório e seu conteúdo para um arquivo zip (usando Java), então qualquer conselho adicional sobre os nomes dos diretórios zip seria apreciado.

Um “guia abrangente” de caracteres proibidos de nomes de arquivos não funcionará no Windows, pois reserva nomes de arquivos e caracteres. Sim, caracteres como * " ? E outros são proibidos, mas há um número infinito de nomes compostos apenas de caracteres válidos que são proibidos. Por exemplo, espaços e pontos são caracteres de nome de arquivo válidos, mas nomes compostos apenas desses caracteres são proibidos.

O Windows não distingue entre maiúsculas e minúsculas, portanto, você não pode criar uma pasta chamada A se já existir uma chamada com o nome. Pior, nomes aparentemente permitidos como PRN e CON , e muitos outros, são reservados e não permitidos. O Windows também tem várias restrições de tamanho; um nome de arquivo válido em uma pasta pode se tornar inválido se for movido para outra pasta. As regras para nomear arquivos e pastas estão no MSDN.

Você não pode, em geral, usar o texto gerado pelo usuário para criar nomes de diretório do Windows. Se você quiser permitir que os usuários nomeiem o que quiserem, será necessário criar nomes seguros como A , AB , A2 e outros, armazenar nomes gerados pelo usuário e seus equivalentes de caminho em um arquivo de dados do aplicativo e executar o mapeamento de caminho em seu aplicativo. .

Se você absolutamente deve permitir nomes de pasta gerados pelo usuário, a única maneira de saber se eles são inválidos é capturar exceções e assumir que o nome é inválido. Mesmo isso é repleto de perigos, pois as exceções lançadas para access negado, unidades offline e espaço em disco sobrepõem-se àquelas que podem ser lançadas para nomes inválidos. Você está abrindo uma lata enorme de dor.

Vamos simplificar e responder a pergunta primeiro.

  1. Os caracteres ASCII imprimíveis proibidos são:

    • Linux / Unix:

       / (forward slash) 
    • Janelas:

       < (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 não imprimíveis

    Se os seus dados forem provenientes de uma fonte que permita caracteres não imprimíveis, haverá mais para verificar.

    • Linux / Unix:

       0 (NULL byte) 
    • Janelas:

       0-31 (ASCII control characters) 

    Nota: Embora seja legal nos filesystems Linux / Unix criar arquivos com caracteres de controle no nome do arquivo, pode ser um pesadelo para os usuários lidarem com esses arquivos .

  3. Nomes de arquivos reservados

    Os seguintes nomes de arquivos são reservados:

    • Janelas:

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

    • Janelas:

      Nomes de arquivo não podem terminar em um espaço ou ponto.

No Linux e em outros sistemas relacionados ao Unix, existem apenas dois caracteres que não podem aparecer no nome de um arquivo ou diretório, e esses são NUL '\0' e slash '/' . A barra, é claro, pode aparecer em um nome de caminho, separando os componentes do diretório.

Rumor 1 diz que Steven Bourne (da fama ‘shell’) tinha um diretório contendo 254 arquivos, um para cada letra (código de caractere) que pode aparecer em um nome de arquivo (excluindo / , '\0' ; o nome . o diretório atual, é claro). Ele foi usado para testar o shell Bourne e rotineiramente arruinou programas imprudentes, como programas de backup.

Outras pessoas cobriram as regras do Windows.

Observe que o MacOS X possui um sistema de arquivos sem distinção entre maiúsculas e minúsculas.


1 Foi Kernighan & Pike em The Practice of Programming que disse isso no Capítulo 6, Testes, §6.5 Testes de Estresse:

Quando Steve Bourne estava escrevendo seu shell Unix (que veio a ser conhecido como shell Bourne), ele criou um diretório de 254 arquivos com nomes de um caractere, um para cada valor de byte, exceto '\0' e slash, os dois caracteres que não pode aparecer em nomes de arquivos Unix. Ele usou esse diretório para todos os tipos de testes de correspondência de padrões e tokenização. (Obviamente, o diretório de teste foi criado por um programa.) Durante anos, esse diretório era a ruína dos programas de leitura de trees de arquivos; testou-os para a destruição.

Em vez de criar uma lista negra de caracteres, você poderia usar uma lista de permissions . Considerando tudo, o intervalo de caracteres que faz sentido em um contexto de nome de arquivo ou diretório é bem curto e, a menos que você tenha alguns requisitos de nomenclatura muito específicos, seus usuários não o manterão em seu aplicativo se não puderem usar toda a tabela ASCII.

Ele não resolve o problema de nomes reservados no sistema de arquivos de destino, mas com uma lista de permissions é mais fácil mitigar os riscos na origem.

Nesse espírito, esse é um intervalo de caracteres que pode ser considerado seguro:

  • Letras (az AZ) – caracteres Unicode, se necessário
  • Dígitos (0-9)
  • Sublinhado (_)
  • Hífen (-)
  • Espaço
  • Ponto (.)

E qualquer caractere seguro adicional que você queira permitir. Além disso, você só precisa impor algumas regras adicionais sobre espaços e pontos . Isso geralmente é suficiente:

  • O nome deve conter pelo menos uma letra ou número (para evitar apenas pontos / espaços)
  • O nome deve começar com uma letra ou número (para evitar pontos / espaços iniciais)

Isso já permite nomes bastante complexos e sem sentido. Por exemplo, esses nomes seriam possíveis com essas regras e seriam nomes de arquivos válidos no Windows / Linux:

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

Em essência, mesmo com poucos caracteres na lista de permissions, você ainda deve decidir o que realmente faz sentido e validar / ajustar o nome de acordo. Em um dos meus aplicativos, usei as mesmas regras acima, mas tirei pontos e espaços duplicados.

Bem, se apenas para fins de pesquisa, a sua melhor aposta é olhar para esta input da Wikipédia em nomes de arquivo .

Se você quiser escrever uma function portátil para validar a input do usuário e criar nomes de arquivos com base nisso, a resposta curta é não . Dê uma olhada em um módulo portátil como o File :: Spec do Perl para ter um vislumbre de todos os saltos necessários para realizar uma tarefa tão “simples”.

A maneira mais fácil de obter o Windows para lhe dizer a resposta é tentar renomear um arquivo via Explorer e digitar / para o novo nome. O Windows exibirá uma checkbox de mensagem informando a lista de caracteres ilegais.

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

https://support.microsoft.com/pt-br/kb/177506

Para o Windows, você pode verificá-lo usando o PowerShell

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

Para exibir códigos UTF-8, você pode converter

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

A partir de 18/04/2017, nenhuma lista simples de caracteres e nomes de arquivos em preto ou branco é evidente entre as respostas a este tópico – e há muitas respostas.

A melhor sugestão que eu poderia sugerir era deixar o usuário nomear o arquivo como ele quiser. Usando um manipulador de erros quando o aplicativo tenta salvar o arquivo, detecte exceções, assuma que o nome do arquivo seja o culpado (obviamente, depois de certificar-se de que o caminho de salvamento também foi bom) e solicite ao usuário um novo nome de arquivo. Para obter melhores resultados, coloque esse procedimento de verificação em um loop que continua até que o usuário acerte ou desista. Funcionou melhor para mim (pelo menos em VBA).

Exemplo de código VBA: (será adicionado ainda hoje)

Embora os únicos chars Unix ilegais possam ser / e NULL , embora algumas considerações sobre a interpretação da linha de comando devam ser incluídas.

Por exemplo, embora possa ser legal nomear um arquivo 1>&2 ou 2>&1 no Unix, nomes de arquivo como este podem ser mal interpretados quando usados ​​em uma linha de comando.

Da mesma forma, pode ser possível nomear um arquivo $PATH , mas ao tentar acessá-lo a partir da linha de comando, o shell converterá $PATH em seu valor variável.

Ao criar atalhos da Internet no Windows, para criar o nome do arquivo, ele ignora os caracteres ilegais, exceto a barra, que é convertida para menos.

Em shells Unix, você pode citar quase todos os caracteres entre aspas simples ' . Exceto a cota única em si, e você não pode expressar caracteres de controle, porque \ não é expandido. É possível acessar a aspas simples de dentro de uma string entre aspas, porque você pode concatenar strings com aspas simples e duplas, como 'I'"'"'m' que pode ser usado para acessar um arquivo chamado "I'm" (double citação também é possível aqui).

Então você deve evitar todos os caracteres de controle, porque eles são muito difíceis de entrar no shell. O resto ainda é engraçado, especialmente os arquivos que começam com um traço, porque a maioria dos comandos os lê como opções, a menos que você tenha dois traços -- antes ou você os especifique com ./ , que também oculta o início - .

Se você quer ser legal, não use nenhum dos caracteres que o shell e os comandos típicos usam como elementos sintáticos, às vezes dependentes de posição, por exemplo, você ainda pode usar - mas não como primeiro caractere; mesmo com . , você pode usá-lo como primeiro caractere apenas quando você quiser (“arquivo oculto”). Quando você é malvado, seus nomes de arquivos são sequências de escape do VT100 ;-), de modo que um ls garble a saída.

Eu tive a mesma necessidade e estava procurando referências de recomendação ou padrão e me deparei com este segmento. Minha lista negra atual de caracteres que devem ser evitados em nomes de arquivos e diretórios é:

 $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" -> "@" };