为什么Windows中存在260个字符的路径长度限制?

时间:2009-12-10 11:18:17

标签: windows path limit

我在不合时宜的时刻曾多次反对这个问题:

  • 尝试使用具有深层路径的开源Java项目
  • 在源代码管理中存储深度Fitnesse wiki树
  • 尝试使用Bazaar导入源代码管理树时出错

为什么存在此限制?

为什么还没有删除它?

你如何应对路径限制? ......而且,切换到Linux或Mac OS X不是这个问题的有效答案;)

11 个答案:

答案 0 :(得分:211)

引用这篇文章https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

  

最大路径长度限制

     

在Windows API中(以下段落中讨论了一些例外),路径的最大长度为 MAX_PATH ,定义为260个字符。本地路径按以下顺序构成:驱动器号,冒号,反斜杠,由反斜杠分隔的名称组件以及终止空字符。例如,驱动器D上的最大路径是“D:\ 一些256个字符的路径字符串< NUL>”其中“< NUL>”表示当前系统代码页的不可见的终止空字符。 (字符<>在此处用于视觉清晰度,不能是有效路径字符串的一部分。)

现在我们看到它是1 + 2 + 256 + 1或[drive] [:\] [path] [null] = 260.可以假设256是DOS天数的合理固定字符串长度。回到DOS API我们意识到系统跟踪每个驱动器的当前路径,我们有26 (32 with symbols) maximum drives(和当前目录)。

INT 0x21 AH = 0x47表示“此函数返回没有驱动器号和初始反斜杠的路径描述。”因此我们看到系统将CWD存储为一对(驱动器,路径)并且您要求路径通过指定驱动器(1 = A,2 = B,...),如果指定0,则它假定INT 0x21 AH = 0x15 AL = 0x19返回的驱动器路径。所以现在我们知道为什么它是260而不是256,因为这4个字节没有存储在路径字符串中。

为什么是256字节的路径字符串,因为640K就足够了。

答案 1 :(得分:142)

这并不严格,因为NTFS文件系统支持最多32k字符的路径。您可以使用win32 api和路径“\\?\”作为前缀,使用超过260个字符。

详细解释.Net BCL team blog的长路径 一个小的摘录突出了长路径的问题

  

另一个问题是暴露长路径支持会导致不一致的行为。具有\\?\前缀的长路径可用于大多数与文件相关的Windows API,但不能用于所有Windows API。例如,如果文件名长于MAX_PATH,则将模块映射到调用进程的地址的LoadLibrary将失败。所以这意味着MoveFile将允许您将DLL移动到一个位置,使其路径超过260个字符,但是当您尝试加载DLL时,它将失败。整个Windows API都有类似的例子;存在一些变通方法,但它们是逐案处理的。

答案 2 :(得分:98)

问题是为什么限制仍然存在。当然,现代Windows可以增加MAX_PATH的一面以允许更长的路径。为什么没有删除限制?

  • 无法删除的原因是Windows承诺永远不会改变。

通过API合同,Windows保证所有应用程序标准文件API永远不会返回超过260个字符的路径。

请考虑以下正确代码:

WIN32_FIND_DATA findData;

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

Windows 保证我的程序将填充我的WIN32_FIND_DATA结构:

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

我的应用程序没有声明常量MAX_PATH的值,Windows API也是如此。我的应用程序使用了定义的值。

我的结构已正确定义,并且仅分配592个字节。这意味着我只能接收小于260个字符的文件名。 Windows 承诺我如果我正确地编写了我的应用程序,我的应用程序将来会继续使用。

如果Windows允许文件名长于260个字符,那么我现有的应用程序(正确使用正确的API)将会失败。

对于任何要求Microsoft更改MAX_PATH常量的人,他们首先需要确保没有现有的应用程序失败。例如,我仍然拥有并使用在Windows 3.11上运行的Windows应用程序。它仍然在64位Windows 10上运行。这就是向后兼容性所带来的。

Microsoft 确实创建了一种使用完整的32,768个路径名的方法;但是他们必须创建一个新的API合同来完成它。例如,您应该使用 Shell API 来枚举文件(因为并非所有文件都存在于硬盘驱动器或网络共享上)。

但他们也必须不破坏现有的用户应用程序。绝大多数应用程序使用shell api进行文件工作。每个人都只需拨打FindFirstFile / FindNextFile并将其称为一天。

答案 3 :(得分:53)

从Windows 10.您可以remove the limitation修改注册表项。

  

提示从Windows 10版本1607开始,MAX_PATH限制已从常见的Win32文件和目录功能中删除。但是,您必须选择加入新行为。

     

注册表项允许您启用或禁用新的长路径行为。要启用长路径行为,请在HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled处设置注册表项(类型:REG_DWORD)。在第一次调用受影响的Win32文件或目录函数(后面的列表)之后,系统(每个进程)将缓存键的值。在进程的生命周期内不会重新加载注册表项。为了使系统上的所有应用程序能够识别密钥的值,可能需要重新启动,因为某些进程可能在密钥设置之前已经启动。   注册表项也可以通过Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths的组策略进行控制。   您还可以通过清单启用每个应用程序的新长路径行为:

<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>

答案 4 :(得分:29)

您可以将文件夹作为驱动器安装。在命令行中,如果您有路径C:\path\to\long\folder,则可以使用以下方式将其映射到驱动器号X:

subst x: \path\to\long\folder

答案 5 :(得分:15)

应对路径限制的一种方法是使用符号链接缩短路径条目。

例如:

  1. 创建一个C:\p目录以保留到长路径的短链接
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. C:\p\foo添加到您的路径而不是长路径

答案 6 :(得分:7)

至于为什么这仍然存在 - MS并不认为它是一个优先事项,并且在推进其操作系统方面具有向后兼容性(至少在这种情况下)。

我使用的解决方法是使用&#34;短名称&#34;对于路径中的目录,而不是其标准的人类可读版本。所以例如。 C:\Program Files\我会使用C:\PROGRA~1\你可以使用dir /x找到等同的短名称。

答案 7 :(得分:7)

至于如何应对Windows上的路径大小限制 - 使用7zip打包(并解压缩)路径长度敏感文件似乎是一种可行的解决方法。我已经用它来传输几个IDE安装(那些Eclipse插件路径,yikes!)和一堆自动生成的文档,到目前为止还没有一个问题。

不确定它是如何规避Windows设置的260字符限制(来自技术PoV),但是嘿,它有效!

有关其SourceForge页面here的详细信息:

  

&#34; NTFS实际上可以支持最多32,000个字符的路径名   。长度&#34;

     

7-zip也支持如此长的名字。

     

但它在SFX代码中被禁用了。有些用户不喜欢漫长的路径,因为   他们不懂得如何与他们合作。这就是我的原因   在SFX代码中禁用它。

release notes

  

9.32 alpha 2013-12-01

     
      
  • 改进了对超过260个字符的文件路径名的支持。
  •   
     

4.44 beta 2007-01-20

     
      
  • 7-Zip现在支持超过260个字符的文件路径名。
  •   

重要提示:为了使其正常工作,您需要在7zip&#34;提取&#34;中指定目标路径。直接对话,而不是拖动&amp;将文件放入目标文件夹。否则,&#34; Temp&#34;文件夹将用作临时缓存,并且一旦Windows资源管理器开始将文件移动到其最终的休息位置,您就会反弹到相同的260字符限制中。有关详细信息,请参阅对this question的回复。

答案 8 :(得分:6)

您可以使用PowerShell启用长路径名:

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

另一个版本是在Computer Configuration / Administrative Templates / System / Filesystem中使用组策略:

Group Policy Editor

答案 9 :(得分:4)

确实如此,由于某些原因它是默认值,但您可以使用此注册表项轻松覆盖它:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

请参阅:https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/

答案 10 :(得分:2)

另一种处理方法是使用Cygwin,具体取决于你想对文件做什么(例如,如果Cygwin命令符合你的需要)

例如,它允许复制,移动或重命名甚至Windows资源管理器都无法访问的文件。或者当然要处理它们的内容,如md5sum,grep,gzip等。

对于您正在编码的程序,您可以将它们链接到Cygwin DLL,它可以使它们使用长路径(虽然我没有测试过)