Nomear arquivos, caminhos e namespaces
Os sistemas de arquivos suportados pelo Windows usam o conceito de arquivos e diretórios para acessar dados armazenados em um disco ou dispositivo. Os desenvolvedores do Windows que trabalham com as APIs do Windows para E/S de arquivo e dispositivo devem entender as regras, convenções e limitações de nomes para arquivos e diretórios.
Os dados podem ser acessados de discos, dispositivos e compartilhamentos de rede usando APIs de E/S de arquivo. Arquivos e diretórios, juntamente com namespaces, fazem parte do conceito de um caminho, que é uma representação de cadeia de caracteres de onde obter os dados, sem importar se são de um disco ou de um dispositivo ou de uma conexão de rede para uma operação específica.
Alguns sistemas de arquivos, como o NTFS, dão suporte a arquivos e diretórios vinculados, que também seguem convenções e regras de nomenclatura de arquivos, assim como um arquivo ou diretório regular o faria. Para obter informações adicionais, consulte Links físicos e junções e Ponto de nova análise e operações de arquivo.
Para saber mais sobre como configurar o Windows para dar suporte a caminhos de arquivo longos, consulte Limitação de comprimento máximo de caminho.
Nomes de arquivo e diretório
Todos os sistemas de arquivos seguem as mesmas convenções gerais de nomenclatura para um arquivo individual: um nome de arquivo base e uma extensão opcional, separados por um ponto. No entanto, cada sistema de arquivos, como NTFS, CDFS, exFAT, UDFS, FAT e FAT32, pode ter regras específicas e diferentes sobre a formação dos componentes individuais no caminho para um diretório ou arquivo. Observe que um diretório é simplesmente um arquivo com um atributo especial designando-o como um diretório, mas, caso contrário, deve seguir todas as mesmas regras de nomenclatura que um arquivo regular. Como o termo diretório simplesmente se refere a um tipo especial de arquivo no que diz respeito ao sistema de arquivos, algum material de referência usará o termo geral arquivo para abranger os conceitos de diretórios e arquivos de dados como tal. Por isso, a menos que especificado de outra forma, quaisquer regras de nomenclatura ou uso ou exemplos de um arquivo também devem ser aplicados a um diretório. O termo caminho se refere a um ou mais diretórios, barras invertidas e, possivelmente, um nome de volume. Para obter mais informações, consulte seção Caminhos.
As limitações de contagem de caracteres também podem ser diferentes e variar dependendo do sistema de arquivos e do formato do prefixo de nome de caminho usado. Isso fica ainda mais complexo devido ao suporte para mecanismos compatíveis com versões anteriores. Por exemplo, o sistema de arquivos MS-DOS FAT mais antigo dá suporte a um máximo de oito caracteres para o nome de arquivo base e três caracteres para a extensão, para um total de 12 caracteres, incluindo o separador de pontos. Isso é comumente conhecido como um nome de arquivo 8.3. Os sistemas de arquivos do NTFS e FAT do Windows não estão limitados a nomes de arquivo 8.3, pois têm suporte a nomes de arquivo longos, mas ainda dão suporte à versão 8.3 de nomes de arquivo longos.
Convenções de nomenclatura
As seguintes regras fundamentais permitem que os aplicativos criem e processem nomes válidos para arquivos e diretórios, sem importar o sistema de arquivos:
Use um ponto para separar o nome de arquivo base da extensão no nome de um diretório ou arquivo.
Use a barra invertida (\) para separar os componentes de um caminho. A barra invertida separa o nome de arquivo do caminho para ele e um nome de diretório de outro nome de diretório em um caminho. Você não pode usar a barra invertida no nome de arquivo ou diretório real porque é um caractere reservado que separa os nomes em componentes.
Use a barra invertida conforme necessário como parte dos nomes de volume, por exemplo, o "C:\" em "C:\path\file" ou "\\server\share" em "\\server\share\path\file" para nomes da UNC (Convenção de Nomenclatura Universal). Para obter mais informações sobre nomes da UNC, consulte a seção Limitação máxima do comprimento do caminho.
Não suponha a diferenciação de maiúsculas e minúsculas. Por exemplo, considere os nomes OSCAR, Oscar e oscar como sendo o mesmo, embora alguns sistemas de arquivos (como um sistema de arquivos compatível com a POSIX) possam considerá-los diferentes. Observe que o NTFS dá suporte à semântica da POSIX para diferenciação de maiúsculas e minúsculas, mas esse não é o comportamento padrão. Para obter mais informações, consulte CreateFile.
Os designadores de volume (letras de unidade) não diferenciam maiúsculas de minúsculas. Por exemplo, "D:\" e "d:\" se referem ao mesmo volume.
Use qualquer caractere na página de código atual para um nome, incluindo caracteres Unicode e caracteres no conjunto de caracteres estendido (128–255), exceto pelo seguinte:
Os seguintes caracteres reservados:
- < (menor que)
- > (maior que)
- : (dois pontos)
- "(aspas duplas)
- / (barra)
- \ (barra invertida)
- | (barra vertical ou pipe)
- ? (ponto de interrogação)
- * (asterisco)
Valor inteiro zero, às vezes chamado de caractere NUL ASCII.
Caracteres cujas representações de inteiro estão no intervalo de 1 a 31, exceto para fluxos de dados alternativos em que esses caracteres são permitidos. Para obter mais informações sobre fluxos de arquivos, consulte Fluxos de arquivos.
Qualquer outro caractere que o sistema de arquivos de destino não permita.
Use um ponto como um componente de diretório em um caminho para representar o diretório atual, por exemplo, ".\temp.txt". Para obter mais informações, confira Caminhos.
Use dois pontos consecutivos (..) como um componente de diretório em um caminho para representar o pai do diretório atual, por exemplo, ".. \temp.txt". Para obter mais informações, confira Caminhos.
Não use os seguintes nomes reservados para o nome de um arquivo:
CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, COM¹, COM², COM³, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, LPT¹, LPT² e LPT³. Evite também esses nomes seguidos imediatamente por uma extensão; por exemplo, NUL.txt e NUL.tar.gz são equivalentes a NUL. Para obter mais informações, consulte Namespaces.
Observação
O Windows reconhece os dígitos sobrescritos ISO/IEC 8859-1 de 8 bits ¹, ² e ³ como dígitos e os trata como partes válidas dos nomes de dispositivo COM# e LPT#, tornando-os reservados em todos os diretórios. Por exemplo,
echo test > COM¹
falha ao criar um arquivo.Não termine um arquivo ou nome de diretório com um espaço ou um ponto. Embora o sistema de arquivos subjacente possa dar suporte a esses nomes, o shell do Windows e a interface do usuário não dão. No entanto, é aceitável especificar um ponto como o primeiro caractere de um nome. Por exemplo, ".temp".
Nomes Curtos vs. Longos
Um nome de arquivo longo é considerado qualquer nome de arquivo que exceda a convenção de nomenclatura de estilo curto ms-DOS (também chamado 8.3). Quando você cria um nome de arquivo longo, o Windows também pode criar uma forma curta 8.3 do nome, chamada de alias 8.3 ou nome curto, e também armazená-la no disco. Esse aliasing 8.3 pode ser desabilitado por motivos de desempenho em todo o sistema ou para um volume especificado, dependendo do sistema de arquivos específico.
Windows Server 2008, Windows Vista, Windows Server 2003 e Windows XP: a atribuição de alias 8.3 não pode ser desabilitada para volumes especificados até o Windows 7 e o Windows Server 2008 R2.
Em muitos sistemas de arquivos, um nome de arquivo conterá um til (~) dentro de cada componente de um nome que seja longo demais para atender às regras de nomenclatura 8.3.
Observação
Nem todos os sistemas de arquivos seguem a convenção de substituição de til e os sistemas podem ser configurados para desabilitar a geração de alias 8.3, mesmo que normalmente deem suporte a ela. Portanto, não faça a suposição de que o alias 8.3 já existe no disco.
Para solicitar nomes de arquivo 8.3, nomes de arquivo longos ou o caminho completo de um arquivo do sistema, considere as seguintes opções:
- Para obter a forma 8.3 de um nome de arquivo longo, use a função GetShortPathName.
- Para obter a versão de nome de arquivo longo de um nome curto, use a função GetLongPathName.
- Para obter o caminho completo para um arquivo, use a função GetFullPathName.
Em sistemas de arquivos mais recentes, como NTFS, exFAT, UDFS e FAT32, o Windows armazena os nomes de arquivo longos no disco em Unicode, o que significa que o nome de arquivo longo original sempre é preservado. Isso é verdadeiro mesmo se um nome de arquivo longo contiver caracteres estendidos, sem importar a página de código que esteja ativa durante uma operação de leitura ou gravação de disco.
Os arquivos que usam nomes de arquivo longos podem ser copiados entre partições do sistema de arquivos do NTFS e partições do sistema de arquivos FAT do Windows sem perder nenhuma informação de nome de arquivo. Isso pode não ser verdade para o MS-DOS FAT mais antigo e alguns tipos de sistemas de arquivos CDFS (CD-ROM), dependendo do nome de arquivo real. Nesse caso, o nome de arquivo curto será substituído, se possível.
Caminhos
O caminho para um arquivo especificado consiste em um ou mais componentes separados por um caractere especial (uma barra invertida), com cada componente geralmente sendo um nome de diretório ou nome de arquivo, mas com algumas exceções notáveis discutidas abaixo. Geralmente, é essencial para a interpretação pelo sistema de um caminho sobre como é o início ou prefixo do caminho. Esse prefixo determina o namespace que o caminho está usando e, além disso, quais caracteres especiais são usados em qual posição dentro do caminho, incluindo o último caractere.
Se um componente de um caminho for um nome de arquivo, ele deverá ser o último componente.
Cada componente de um caminho também será restrito pelo comprimento máximo especificado para um sistema de arquivos específico. Em geral, essas regras se enquadram em duas categorias: curta e longa. Observe que os nomes de diretório são armazenados pelo sistema de arquivos como um tipo especial de arquivo, mas as regras de nomenclatura para arquivos também se aplicam a nomes de diretório. Para resumir, um caminho é simplesmente a representação de cadeia de caracteres da hierarquia entre todos os diretórios existentes para um determinado arquivo ou nome de diretório.
Caminhos Totalmente Qualificados vs. Relativos
Para funções da API do Windows que manipulam arquivos, os nomes de arquivo geralmente podem ser relativos ao diretório atual, enquanto algumas APIs exigem um caminho totalmente qualificado. Um nome de arquivo será relativo ao diretório atual se ele não começar com um dos seguintes:
- Um nome UNC de qualquer formato, que sempre começa com dois caracteres de barra invertida ("\\"). Para obter mais informações, consulte a próxima seção.
- Um designador de disco com uma barra invertida, por exemplo , "C:\" ou "d:\".
- Uma única barra invertida, por exemplo, "\diretório" ou "\file.txt". Isso também é conhecido como caminho absoluto.
Se um nome de arquivo começar apenas com um designador de disco, mas não a barra invertida após os dois pontos, ele será interpretado como um caminho relativo para o diretório atual na unidade com a letra especificada. Observe que o diretório atual pode ou não ser o diretório raiz, dependendo do que foi definido durante a operação mais recente de "alterar diretório" nesse disco. Seguem exemplos desse formato:
- "C:tmp.txt" se refere a um arquivo chamado "tmp.txt" no diretório atual na unidade C.
- "C:tempdir\tmp.txt" se refere a um arquivo em um subdiretório para o diretório atual na unidade C.
Um caminho também será considerado relativo se contiver "dois pontos", ou seja, dois pontos juntos em um componente do caminho. Esse especificador especial é usado para distinguir o diretório acima do diretório atual, também conhecido como "diretório pai". Seguem exemplos desse formato:
- ".. \tmp.txt" especifica um arquivo chamado tmp.txt localizado no pai do diretório atual.
- ".. \.. \tmp.txt" especifica um arquivo que está dois diretórios acima do diretório atual.
- ".. \tempdir\tmp.txt" especifica um arquivo chamado tmp.txt localizado em um diretório chamado tempdir que é um diretório par do diretório atual.
Caminhos relativos podem combinar ambos os tipos de exemplo, como, por exemplo, "C:..\tmp.txt". Isso é útil porque, embora o sistema mantenha o controle da unidade atual juntamente com o diretório atual dessa unidade, ele também mantém o controle dos diretórios atuais em cada uma das diferentes letras da unidade (se o sistema tiver mais de uma), sem importar qual designador de unidade está definido como a unidade atual.
Limitação Máxima do Comprimento do Caminho
Em edições do Windows anteriores ao Windows 10 versão 1607, o comprimento máximo de um caminho é MAX_PATH, que é definido como 260 caracteres. Em versões posteriores do Windows, é necessário alterar uma chave de registro ou usar a ferramenta Política de Grupo para remover o limite. Consulte Limitação máxima do comprimento do caminho para obter detalhes completos.
Namespaces
Há duas categorias principais de convenções de namespace usadas nas APIs do Windows, normalmente conhecidas como namespaces do NT e namespaces do Win32. O namespace do NT foi projetado para ser o namespace de nível mais baixo no qual outros subsistemas e namespaces poderiam existir, incluindo o subsistema do Win32 e, por extensão, os namespaces do Win32. A POSIX é outro exemplo de um subsistema no Windows criado com base no namespace do NT. As versões iniciais do Windows também definiram vários nomes predefinidos ou reservados para determinados dispositivos especiais, como portas de comunicação (serial e paralela) e o console de exibição padrão, como parte do que agora é chamado de namespace de dispositivo do NT e ainda têm suporte nas versões atuais do Windows para compatibilidade com versões anteriores.
Namespaces de arquivo do Win32
O prefixo e as convenções do namespace do Win32 são resumidos nesta seção e na seção a seguir, com descrições de como são usados. Observe que esses exemplos se destinam ao uso com as funções da API do Windows e não funcionam necessariamente com aplicativos de shell do Windows, como o Windows Explorer. Por esse motivo, há uma gama maior de caminhos possíveis do que normalmente está disponível em aplicativos de shell do Windows e os aplicativos do Windows que aproveitam isso podem ser desenvolvidos usando essas convenções de namespace.
Para E/S de arquivo, o prefixo "\\?\" para uma cadeia de caracteres de caminho informa às APIs do Windows para desabilitar toda a análise de cadeia de caracteres e enviar a cadeia de caracteres que a segue diretamente para o sistema de arquivos. Por exemplo, se o sistema de arquivos der suporte a caminhos grandes e nomes de arquivo, você poderá exceder os limites de MAX_PATH que, de outra forma, são impostos pelas APIs do Windows.
Como ele desativa a expansão automática da cadeia de caracteres de caminho, o prefixo "\\?\" também permite o uso de ".." e "." nos nomes de caminho, o que pode ser útil se você estiver tentando executar operações em um arquivo com esses especificadores de caminho relativo reservados como parte do caminho totalmente qualificado.
Muitas, mas nem todas as APIs de E/S de arquivo dão suporte a "\\?\"; você deve examinar o tópico de referência de cada API para ter certeza.
Observe que as APIs Unicode devem ser usadas para garantir que o prefixo "\\?\" permita que você exceda o MAX_PATH.
Namespaces de dispositivo do Win32
O prefixo "\\.\" acessará o namespace de dispositivo do Win32 em vez do namespace de arquivo do Win32. É assim que o acesso a discos físicos e volumes é realizado diretamente, sem passar pelo sistema de arquivos, se a API der suporte a esse tipo de acesso. Você pode acessar muitos dispositivos diferentes de discos dessa maneira (usando as funções CreateFile e DefineDosDevice, por exemplo).
Por exemplo, se quiser abrir a porta serial 1 de comunicações do sistema, você poderá usar "COM1" na chamada para a função CreateFile. Isso funciona porque COM1–COM9 fazem parte dos nomes reservados no namespace do NT, embora o uso do prefixo "\\.\" também funcione com esses nomes de dispositivo. Em comparação, se você tiver uma placa de expansão serial de 100 portas instalada e quiser abrir o COM56, não poderá abri-la usando "COM56" porque não há nenhum namespace do NT predefinido para COM56. Você precisará abri-lo usando "\\.\COM56" porque "\\.\" vai diretamente para o namespace do dispositivo sem tentar localizar um alias predefinido.
Outro exemplo de uso do namespace de dispositivo do Win32 é usar a função CreateFile com "\\.\PhysicalDriveX" (em que X é um valor inteiro válido) ou "\\.\CdRomX". Isso permite que você acesse esses dispositivos diretamente, ignorando o sistema de arquivos. Isso funciona porque esses nomes de dispositivo são criados pelo sistema à medida que esses dispositivos são enumerados e alguns drivers também criam outros aliases no sistema. Por exemplo, o driver de dispositivo que implementa o nome "C:\" tem seu próprio namespace que também é o sistema de arquivos.
As APIs que passam pela função CreateFile geralmente funcionam com o prefixo "\\.\" porque CreateFile é a função usada para abrir arquivos e dispositivos, dependendo dos parâmetros usados.
Se estiver trabalhando com funções da API do Windows, você deverá usar o prefixo "\\.\" para acessar somente dispositivos e não arquivos.
A maioria das APIs não dá suporte a "\\.\"; somente aquelas projetadas para trabalhar com o namespace de dispositivo o reconhecerão. Sempre verifique o tópico de referência para cada API para ter certeza.
Namespaces do NT
Também há APIs que permitem o uso da convenção de namespace do NT, mas o Gerenciador de Objetos do Windows torna isso desnecessário na maioria dos casos. Para ilustrar, é útil procurar os namespaces do Windows no navegador de objetos do sistema usando a ferramenta WinObj do Windows Sysinternals. Quando você executa essa ferramenta, o que você vê é o namespace do NT começando na raiz ou "\". A subpasta chamada "Global??" é onde reside o namespace do Win32. Os objetos de dispositivo nomeados residem no namespace do NT dentro do subdiretório "Device". Aqui você também pode encontrar Serial0 e Serial1, os objetos de dispositivo que representam as duas primeiras portas COM, se estiverem presentes no sistema. Um objeto de dispositivo que representa um volume seria algo como "HarddiskVolume1", embora o sufixo numérico possa variar. O nome "DR0" no subdiretório "Harddisk0" é um exemplo do objeto de dispositivo que representa um disco e assim por diante.
Para tornar esses objetos de dispositivo acessíveis por aplicativos do Windows, os drivers de dispositivo criam um link simbólico (symlink) no namespace do Win32, "Global??", para seus respectivos objetos de dispositivo. Por exemplo, COM0 e COM1 no subdiretório "Global??" são simplesmente links para Serial0 e Serial1, "C:" é um symlink para HarddiskVolume1, "Physicaldrive0" é um symlink para DR0 e assim por diante. Sem um symlink, um dispositivo especificado "Xxx" não estará disponível para nenhum aplicativo do Windows usando convenções de namespace do Win32, conforme descrito anteriormente. No entanto, um identificador pode ser aberto para esse dispositivo usando as APIs que dão suporte ao caminho absoluto do namespace do NT do formato "\Device\Xxx".
Com a adição de suporte a vários usuários por meio de Serviços de Terminal e máquinas virtuais, tornou-se ainda mais necessário virtualizar o dispositivo raiz em todo o sistema dentro do namespace do Win32. Isso foi feito adicionando o symlink chamado "GLOBALROOT" ao namespace do Win32, que você pode ver no subdiretório "Global??" da ferramenta de navegador WinObj discutida anteriormente, bem como acessar por meio do caminho "\\?\GLOBALROOT". Esse prefixo garante que o caminho a seguir procure o caminho raiz verdadeiro do gerenciador de objetos do sistema e não um caminho dependente da sessão.