Por que o limite de comprimento do caminho de 260 caracteres existe no Windows?

390

Eu já enfrentei esse problema algumas vezes em momentos inoportunos:

  • Tentando trabalhar em projetos Java de código aberto com caminhos profundos
  • Armazenando árvores wiki profundas do Fitnesse no controle de origem
  • Erro ao tentar usar o Bazaar para importar minha árvore de controle de origem

Por que esse limite existe?

Por que ainda não foi removido?

Como você lida com o limite de caminho? E não, mudar para Linux ou Mac OS X não é uma resposta válida para esta pergunta;)

Jeffrey Cameron
fonte
8
@Artelius: Na verdade, o Windows (pelo menos a partir do Win2K) suporta pontos de junção ( en.wikipedia.org/wiki/NTFS_junction_point ), e o Vista em diante suporta os links simbólicos do NT ( en.wikipedia.org/wiki/NTFS_symbolic_link ). De qualquer forma, embora os links simbólicos possam ajudar a tornar os caminhos mais longos / aninhados mais amigáveis, não consigo pensar em como os links simbólicos ajudariam se você estivesse atingindo os limites de comprimento do caminho.
Ashutosh Mehra
8
Mesmo que esse limite não existisse, sempre existem muitos outros limites, e cada um deles pode ser irritante em algum momento. A questão é por que esse limite é tão baixo? Após a era da 8.3, e com hardware do tamanho de mega / giga, um caminho agora deve ser uma string alocada dinamicamente com um tamanho praticamente ilimitado.
Roland
12
Microsoft está finalmente abordar este problema, no Windows 10 Desenvolver 14352.
Warren P
3
Sim, e parece que você precisa modificar o manifesto do aplicativo para torná-lo consciente do caminho longo.
Warren P
3
@PatrickSzalapski infelizmente, foi fixado visualstudio.uservoice.com/forums/121579-visual-studio/...
phuclv

Respostas:

231

Citando este artigo https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Limitação máxima de comprimento do caminho

Na API do Windows (com algumas exceções discutidas nos parágrafos a seguir), o comprimento máximo de um caminho é MAX_PATH , definido como 260 caracteres. Um caminho local é estruturado na seguinte ordem: letra da unidade, dois pontos, barra invertida, componentes de nome separados por barras invertidas e um caractere nulo final. Por exemplo, o caminho máximo na unidade D é "D: \ alguma cadeia de caracteres de 256 caracteres <NUL>", em que "<NUL>" representa o caractere nulo final invisível para a página de códigos atual do sistema. (Os caracteres <> são usados ​​aqui para maior clareza visual e não podem fazer parte de uma cadeia de caminho válida.)

Agora vemos que é 1 + 2 + 256 + 1 ou [drive] [: \] [path] [null] = 260. Pode-se supor que 256 seja um comprimento de cadeia fixo razoável dos dias do DOS. E voltando às APIs do DOS, percebemos que o sistema rastreava o caminho atual por unidade e temos 26 (32 com símbolos) unidades máximas (e diretórios atuais).

O INT 0x21 AH = 0x47 diz "Esta função retorna a descrição do caminho sem a letra da unidade e a barra invertida inicial". Portanto, vemos que o sistema armazena o CWD como um par (unidade, caminho) e você solicita o caminho especificando a unidade (1 = A, 2 = B,…); se você especificar um 0, assumirá o caminho para a unidade retornada por INT 0x21 AH = 0x15 AL = 0x19. Então agora sabemos por que é 260 e não 256, porque esses 4 bytes não são armazenados na cadeia de caminho.

Por que uma string de caminho de 256 bytes, porque 640K é RAM suficiente.

Valli
fonte
21
A API do Windows limita o tamanho, mesmo no sistema operacional mais recente. A Microsoft tem medo de quebrar centenas de milhões de sistemas operacionais em uso hoje se isso mudar, porque eles não têm mais gênios trabalhando para eles que entendem a API por dentro e por fora, como fizeram nas décadas de 1980 e 1990. Não vale a pena mudar o risco. serverfault.com/questions/163419/…
MacGyver 16/07
77
@ MacGyver Desculpe, mas isso é totalmente absurdo. A Microsoft não quer quebrar os milhões de aplicativos mal escritos por aí que assumem coisas sobre o sistema que nunca foram garantidas. Infelizmente, as coisas ficaram da mesma maneira por tanto tempo que os desenvolvedores passaram a confiar nelas, portanto, alterá-las agora quebraria aplicativos de terceiros e a MS ficaria com a culpa.
Básico
25
btw não há nenhuma prova que Gates já disse que o "640K Ram é suficiente para todos" computerworld.com/article/2534312
Patrick Favre
11
@ Basic O limite de 260 caracteres foi garantido pelo Windows. A constante foi declarada como uma constante , uma estrutura foi declarada nos arquivos de cabeçalho do Windows que só tem espaço para 260 caracteres. Não há como mudar isso.
Ian Boyd
35
@ Basic A constante não muda quando compilada no meu aplicativo. Eu executo um aplicativo que foi criado pela última vez em 1994 e ainda é executado hoje no Windows 10. A Microsoft prometeu um certo tamanho binário de um bloco de memória, e o programador seguiu essa regra. Se a Microsoft alterasse a constante, todos os aplicativos existentes, que seguissem corretamente a API de programação, seriam quebrados . Você não pode quebrar a compatibilidade binária.
21815 Ian Boyd
150

Isso não é rigorosamente verdadeiro, pois o sistema de arquivos NTFS suporta caminhos com até 32k caracteres. Você pode usar a API win32 e " \\?\" prefixar o caminho para usar mais de 260 caracteres.

Uma explicação detalhada do caminho longo no blog da equipe .Net BCL .
Um pequeno trecho destaca a questão com caminhos longos

Outra preocupação é o comportamento inconsistente que resultaria expondo o suporte a longo caminho. Caminhos longos com o \\?\prefixo podem ser usados ​​na maioria das APIs do Windows relacionadas a arquivos, mas não em todas as APIs do Windows. Por exemplo, LoadLibrary, que mapeia um módulo para o endereço do processo de chamada, falha se o nome do arquivo for maior que MAX_PATH. Portanto, isso significa que o MoveFile permitirá que você mova uma DLL para um local com um caminho maior que 260 caracteres, mas quando você tenta carregar a DLL, ela falha. Existem exemplos semelhantes nas APIs do Windows; existem algumas soluções alternativas, mas elas são caso a caso.

softveda
fonte
4
É justo, mas isso significa que você precisa usar o P / Invoke em muitos lugares e isso, na minha opinião, reduz a portabilidade do seu código .Net. E se eu quisesse manter a compatibilidade mono?
10119 Jeffrey Cameron
11
Meu argumento era que você pode usar o caminho longo, se realmente quiser. Mas concordo que é uma dor e, pessoalmente, eu evitaria isso também.
softveda
5
Essa deve ser a resposta escolhida. Na verdade, responde à pergunta feita pelo usuário por que esse limite existe e fornece uma solução alternativa. Upvote para a visibilidade
KyleMit
2
Parece-me que a Microsoft precisa corrigir suas APIs, e acho que isso não é uma prioridade. Fiquei surpreso que esse limite ainda exista no Windows 8.
Mas
3
@Mas A "correção" que você deseja foi feita de volta ao Windows XP. Chamar a versão unicode de sua API permitirá acessar o "caminho estendido". Acredito que o Explorer lida automaticamente com isso. Aqui está uma dessas funções que a suporta - msdn.microsoft.com/en-us/library/windows/desktop/… .
Natalie Adams
108

A questão é por que a limitação ainda existe. Certamente o Windows moderno pode aumentar o lado MAX_PATHpara permitir caminhos mais longos. Por que a limitação não foi removida?

  • A razão pela qual não pode ser removido é que o Windows prometeu que nunca mudaria.

Através do contrato de API, o Windows garantiu a todos os aplicativos que as APIs de arquivo padrão nunca retornarão um caminho mais longo que os 260caracteres.

Considere o seguinte código correto :

WIN32_FIND_DATA findData;

FindFirstFile("C:\Contoso\*", ref findData);

O Windows garantiu ao meu programa que ele preencheria minha WIN32_FIND_DATAestrutura:

WIN32_FIND_DATA {
   DWORD    dwFileAttributes;
   FILETIME ftCreationTime;
   FILETIME ftLastAccessTime;
   FILETIME ftLastWriteTime;
   //...
   TCHAR    cFileName[MAX_PATH];
   //..
}

Meu aplicativo não declarou o valor da constante MAX_PATH, a API do Windows fez. Meu aplicativo usou esse valor definido.

Minha estrutura está definida corretamente e aloca apenas o 592total de bytes. Isso significa que eu só consigo receber um nome de arquivo com menos de 260caracteres. O Windows me prometeu que, se eu escrevesse meu aplicativo corretamente, ele continuaria funcionando no futuro.

Se o Windows permitir nomes de arquivos com mais de 260caracteres, meu aplicativo existente (que usou a API correta corretamente) falhará.

Para quem pede que a Microsoft altere a MAX_PATHconstante, primeiro é necessário garantir que nenhum aplicativo existente falhe. Por exemplo, eu ainda possuo e uso um aplicativo do Windows que foi escrito para ser executado no Windows 3.11. Ele ainda roda no Windows 10. de 64 bits. É isso que a compatibilidade com versões anteriores oferece.

Microsoft fez criar uma maneira de usar o total de 32.768 nomes de caminho; mas eles tiveram que criar um novo contrato de API para fazer isso. Por um lado, você deve usar a API do Shell para enumerar arquivos (como nem todos os arquivos existem em um disco rígido ou em um compartilhamento de rede).

Mas eles também precisam não quebrar os aplicativos de usuário existentes. A grande maioria dos aplicativos não usa a API do shell para o trabalho do arquivo. Todo mundo simplesmente liga FindFirstFile/ FindNextFilee liga por dia.

Ian Boyd
fonte
4
@JosiahKeller Se o fizesse, quebraria o contrato originalmente definido para esse método, e isso poderia sobrescrever a memória não intencional e abriria praticamente uma brecha na segurança. A única maneira de corrigir isso é oferecer uma nova API aprimorada (como as variantes compatíveis com Unicode) e esperar que todos recompile / relance todos os seus aplicativos usando a API mais recente.
Rowland Shaw
2
@ Ryios Eu não acho que meus aplicativos Windows existentes sejam executados no Linux.
22615 Ian Boyd
9
A compatibilidade com versões anteriores é boa. Mas acho que evitar esses problemas (muitas vezes realmente desagradáveis) hoje em dia é mais importante do que dar suporte a aplicativos do Windows 3.1. Quantas pessoas enfrentam problemas com caminhos longos? E quantas pessoas ainda usam aplicativos Windows 3.1? Eles até cancelaram o suporte ao Windows XP. Então, por que eles não fazem apenas um comunicado, que no Windows [x] e em aplicativos posteriores que assumem que não haverá um caminho com mais de 260 caracteres, não funcionará conforme o esperado quando eles encontrarem um caminho que é muito longo? Nossos limites de velocidade também não consideram carruagens.
precisa saber é
2
@JuSchu Não são apenas aplicativos do Windows 3.1. Os aplicativos criados hoje usando a API correta não funcionarão.
Ian Boyd
62

No Windows 10. você pode remover a limitação modificando uma chave do Registro.

Dica A partir do Windows 10, versão 1607, as limitações MAX_PATH foram removidas das funções comuns de arquivo e diretório do Win32. No entanto, você deve aceitar o novo comportamento.

Uma chave do Registro permite ativar ou desativar o novo comportamento do caminho longo. Para habilitar o comportamento do caminho longo, defina a chave do Registro em HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled(Tipo REG_DWORD:). O valor da chave será armazenado em cache pelo sistema (por processo) após a primeira chamada para um arquivo Win32 ou função de diretório afetada (lista a seguir). A chave do registro não será recarregada durante a vida útil do processo. Para que todos os aplicativos no sistema reconheçam o valor da chave, uma reinicialização pode ser necessária porque alguns processos podem ter sido iniciados antes da configuração da chave. A chave do registro também pode ser controlada via Diretiva de Grupo em Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. Você também pode habilitar o novo comportamento de caminho longo por aplicativo por meio do manifesto:

<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>
Loop de raiz
fonte
15
Infelizmente, mesmo na versão mais recente do Win10, o próprio File Explorer ainda tem problemas para lidar com o nome do caminho longo. Mesmo "Copiar como caminho" no menu de contexto não funciona conforme o esperado; copia apenas os primeiros 260 caracteres. Você não pode criar uma pasta, copiar / mover / abrir um arquivo ... Me pergunte qual é o sentido dessa alteração.
raymai97
Observe que a afirmação de que a configuração do sistema é independente da configuração do manifesto está incorreta. Ambos são obrigatórios. A política deve ser ativada no nível do sistema e o manifesto deve declarar que o aplicativo tem reconhecimento de longo caminho.
Eryk Sun
Li que fazer essa alteração pode causar problemas de compatibilidade com aplicativos antigos de 32 bits, mas esse tipo de problema com compatibilidade é comum? Eu gostaria de fazer a mudança eu mesmo. lifehacker.com/…
KDP
32

Você pode montar uma pasta como uma unidade. Na linha de comando, se você tiver um caminho, C:\path\to\long\folderpoderá mapeá-lo para a letra da unidade X:usando:

subst x: \path\to\long\folder
jonchang
fonte
Estou recebendo "inválido paramter j:" ao tentar este comando
barrypicker
Isso precisa ser executado em um prompt de comando do administrador (elevado).
Mrchief
Isso falhará nas barras, precisa ser barras invertidas.
Cchamberlain
11
Não tenho certeza se isso se aplica apenas ao Windows 10, no entanto, acabei de descobrir que, ao tentar executar este comando, se executar como administrador, conforme sugerido acima, a unidade não parece estar disponível. Isso ocorre porque o comportamento parece ser semelhante ao mapeamento de uma unidade de rede e é específico da sessão, etc. Por isso, quando eu executei como administrador e usei esse comando, essa sessão poderia usar x: TL; DR executando o comando sem estar no modo administrador.
Jaddie
substé local-session / account - consulte superuser.com/questions/29072/… para saber como torná-lo 'amplo do sistema' #
user2864740
18

Uma maneira de lidar com o limite do caminho é encurtar as entradas do caminho com links simbólicos.

Por exemplo:

  1. crie um C:\pdiretório para manter links curtos para caminhos longos
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. adicione C:\p\fooao seu caminho em vez do caminho longo
JDiMatteo
fonte
3
Não foi necessário criar o diretório primeiro, portanto, a etapa 1 não é necessária.
ohaal
2
Este truque nem sempre funciona como muitos tentam aplicativo para resolver as ligações
nponeccop
A /jopção cria um ponto de montagem de junção para um dispositivo de volume local ou um caminho em um volume local (como uma montagem de ligação Unix). Não cria um link simbólico. É uma distinção importante, pois os pontos de montagem de junção são sempre avaliados em um servidor e devem direcionar dispositivos locais, enquanto os links simbólicos são avaliados no cliente e podem direcionar caminhos remotos (se permitido pela política). Como uma unidade subst.exe (ou seja DefineDosDeviceW), um destino de junção geralmente é limitado a cerca de 4 caracteres K. Na verdade, são 8K caracteres, divididos igualmente entre o caminho substituto e o caminho de exibição.
Eryk Sun
12

Você pode habilitar nomes de caminhos longos usando o PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1 

Outra versão é usar uma Diretiva de Grupo em Computer Configuration/ Administrative Templates/ System/ Filesystem:

Editor de Diretiva de Grupo

MovGP0
fonte
2
Cada aplicativo ainda precisa declarar que está atento ao longo caminho. A Microsoft fez um trabalho ruim ao comunicar isso, fazendo parecer que o manifesto do aplicativo é apenas outra maneira de habilitar esse recurso, em vez de explicar claramente que é um contrato entre o SO (política em nível de sistema) e o aplicativo no qual ambos precisam concordar.
Eryk Sun
8

Por que isso ainda existe - a MS não considera prioritária e valoriza a compatibilidade com versões anteriores do avanço do sistema operacional (pelo menos nesse caso).

Uma solução alternativa que eu uso é usar os "nomes abreviados" para os diretórios no caminho, em vez de suas versões padrão legíveis por humanos. Então, por exemplo, para C:\Program Files\eu usar C:\PROGRA~1\ Você pode encontrar o nome abreviado equivalente dir /x.

Conrad
fonte
11
Nomes de caminhos curtos podem ser desabilitados no registro (ou era o próprio sistema de arquivos?), Portanto, isso realmente não é uma solução confiável.
rubenvb
3
@rubenvb Tenho certeza que a maioria, se não todos, os recursos do Windows podem ser desabilitados no registro, então ¯ \ _ (ツ) _ / ¯
Conrad
A geração de nomes abreviados pode ser desativada para NTFS (e deve ser porque é ineficiente em muitos casos), seja para todo o sistema ou por volume, por isso é uma abordagem não confiável mesmo para caminhos na unidade do sistema, que deve ser NTFS. É possível definir manualmente nomes abreviados em arquivos e diretórios no NTFS, mas isso não se estende a sistemas de arquivos mais novos que não suportam nomes abreviados, como exFAT e ReFS. Os nomes abreviados devem ser considerados um recurso obsoleto que é mantido para compatibilidade em casos limitados, como a antiga API ANSI / OEM usando páginas de código de um e dois bytes.
Eryk Sun
@eryksun Por favor, veja meu comentário anterior sobre como desativar nomes de caminhos curtos. :) Só porque você acha que deve ser considerado obsoleto, não significa que realmente seja. A MS não tem planos de descontinuar esse recurso. (Além disso, por que você está instalando o software Windows em partições exFAT / refs?)
Conrad
Eu ainda digo para usar apenas caminhos de dispositivo não normalizados (ou seja, o prefixo "\\? \"), Pois eles estão sempre disponíveis e óbvios. Por exemplo, traduza PATHe passe para SearchPathW. Também é eficiente, uma vez que a biblioteca de tempo de execução cria "\\? \" Caminhos de dispositivo para o NT de qualquer maneira. Quanto aos sistemas de arquivos mais recentes, provavelmente não veríamos software instalado em um volume exFAT, além de aplicativos portáteis, pois ele não tem segurança, mas eu não descartaria o ReFS. Os usuários instalam programas em locais fora do padrão por razões de conveniência, espaço ou desempenho.
Eryk Sun
7

Sobre como lidar com a limitação do tamanho do caminho no Windows - usar o 7zip para compactar (e descompactar) seus arquivos sensíveis ao comprimento do caminho parece uma solução viável. Usei-o para transportar várias instalações IDE (esses caminhos de plug-in do Eclipse, caramba!) E pilhas de documentação gerada automaticamente e não tive um único problema até agora.

Não tenho muita certeza de como ele foge do limite de 260 caracteres definido pelo Windows (de um PoV técnico), mas, ei, funciona!

Mais detalhes na página do SourceForge aqui :

"O NTFS pode realmente suportar nomes de caminho com até 32.000 caracteres."

O 7-zip também suporta nomes tão longos.

Mas está desativado no código SFX. Alguns usuários não gostam de caminhos longos, pois não sabem como trabalhar com eles. É por isso que eu o desativei no código SFX.

e notas de versão :

9.32 alpha 01-12-2013

  • Suporte aprimorado para nomes de caminho de arquivos com mais de 260 caracteres.

4.44 beta 2007-01-20

  • O 7-Zip agora suporta nomes de caminho de arquivos com mais de 260 caracteres.

NOTA IMPORTANTE: Para que isso funcione corretamente, você precisará especificar o caminho de destino na caixa de diálogo 7zip "Extrair" diretamente, em vez de arrastar e soltar os arquivos na pasta pretendida. Caso contrário, a pasta "Temp" será usada como um cache intermediário e você retornará à mesma limitação de 260 caracteres quando o Windows Explorer começar a mover os arquivos para o "local de descanso final". Veja as respostas a esta pergunta para mais informações.

Priidu Neemre
fonte
3
Eu estava errado, o 7zip e o WinRAR extraem todas as pastas e arquivos. Só que a propriedade de uma pasta no Windows relata apenas o número de pastas e arquivos que não violam a limitação. É como se o Windows Explorer não se aprofundasse mais para descobrir pastas quando o caminho máximo é atingido.
Twisted Whisper
É possível excluir um caminho longo em 7-zip com shift-del.
Laurie Stearn
Resposta curta - uso 7zip para arquivo descompactar um arquivo .zip .... funcionou para mim no Windows 7
andrewcockerham
2

Outra maneira de lidar com isso é usar o Cygwin, dependendo do que você deseja fazer com os arquivos (ou seja, se os comandos do Cygwin atenderem às suas necessidades)

Por exemplo, ele permite copiar, mover ou renomear arquivos que nem o Windows Explorer pode. Ou, é claro, lide com o conteúdo deles, como md5sum, grep, gzip, etc.

Também para os programas que você está codificando, você pode vinculá-los à DLL do Cygwin e permitir que eles usem caminhos longos (ainda não testei isso)

eliblanco87
fonte