当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么Windows中存在260个字符的路径长度限制?》经验,为你挑选了10个好方法。

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

尝试使用深度路径处理开源Java项目

在源代码管理中存储深Fitnesse wiki树

尝试使用Bazaar导入源代码控制树时出错

为什么存在此限制?

为什么还没有被删除?

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



1> 小智..:

引用这篇文章http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath

最大路径长度限制

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

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

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

为什么是256字节的路径字符串,因为640K足够RAM.


",其中""表示当前系统代码页的不可见的终止空字符.(这里使用字符<>是为了清晰,不能成为有效路径字符串的一部分.)
@MacGyver很抱歉,但这完全是胡说八道.微软并不想打破数以百万计写得不好的应用程序那些从未保证过系统的_asume_事件.不幸的是,开发人员依赖它们的时间长得相同,因此现在更改它会破坏第三方应用程序,MS会受到责备.
@Basic一旦将常量编译到我的应用程序中,该常量不会改变.我在1994年运行了一个最后**构建的应用程序**,并且今天仍在Windows 10中运行.微软承诺存储器块的某个二进制大小,程序员遵循该规则.如果Microsoft要更改常量,那么*正确遵循编程API的每个现有应用程序都将被破坏*.您不能破坏二进制兼容性.
顺便说一句,没有证据表明盖茨曾经说过"640K Ram对每个人都足够了"http://www.computerworld.com/article/2534312
即使在最新的操作系统中,Windows API也会限制长度.微软害怕打破今天使用的数亿个操作系统,因为他们不再需要为他们工作的天才,就像他们在20世纪80年代和90年代所做的那样理解内外的API.风险不值得改变它.http://serverfault.com/questions/163419/window-256-characters-path-name-limitation
@Basic Windows保证**的字符限制为**.常量被声明为*常量*,在Windows头文件中声明了一个结构,只有260个字符的空间.没有办法改变它.
@Stewart当你在95上工作正常的非兼容程序停止工作时,操作系统应该做什么因为*别人*创建了一个路径超过260个字符的文件?你如何向用户解释文件`MyDocument.doc`工作正常但是`My Extended Document.doc`没有,除非他们将它移动到另一个突然再次开始工作的目录?停止假装这是一个应该在很久以前修复的简单问题,它比仅仅更改常量要复杂得多.
@Stewart二进制兼容性在Win16和Win32之间断开,是的.但微软努力争取Win16和Win32之间的完整*源代码*兼容性.FAT16,其最大路径为255个字符,是Windows 95必须支持的; 没有必要将常量增加到大于有效的值(因为打破现有应用程序的唯一优点).并且Microsoft*确实*创建了一个支持更长路径的新API - 对于任何想要使用它的人来说(二十一年后人们仍然拒绝使用它)
@Luaan你怎么解释这个?因为这正是今天发生的事情 - 路径不限于260个字符,您可以轻松创建更大的路径,其jus0t函数不接受超过260个字符的路径.
@IanBoyd常量可以在软件版本之间(甚至在构建之间)进行更改.声明常量的原因是它是一个单一的参考点.如果所有软件都在常量上进行了检查,则更改不会成为问题.
...这与他们在system32文件夹中存储64位驱动程序的原因相同,并在SysWOW64文件夹中存储32位驱动程序.制动原始Windows API的风险可能会使它们破产,因为它们的开发人员对它的了解不够.
很好地了解价值260的来源,但实际上并没有回答这个问题.为什么路径的长度完全受限(除了存储路径的可用内存)?即使在MS-DOS下有限制,为什么MS不能在这个时代改变这个事实呢?即使它会破坏将路径写入固定长度的char数组的API,它们也可能引入了一种新的API,它以更灵活的方式工作,并且不推荐使用,后来删除了旧的API.或者过渡仍然是一项正在进行中的工作?
@IanBoyd这个论点存在严重缺陷 - 它无法解释为什么Win16,Win32和Win64之间无法更改.当然,如果Win16限制的路径太长,Win32操作系统中的Win16实现需要以某种方式引发错误.此外,在Windows历史的过程中,二进制兼容性已被破坏了几次.例如,Windows 95无法运行为Windows 2构建的程序.我觉得64位版本的Windows无法运行Win16应用程序.
@Stewart因为执行`char szFilename [260]`的程序。在Windows 95下,大于260的“ MAX_PATH”无效(文件系统不支持大于260的值)。让我们忽略这样一个事实,即在Windows 2000下为Windows 95编写的名为“ char szFilename [MAX_PATH]”的应用程序将失败。让我们忘记二进制应用程序兼容性。假设我们愿意告诉用户他们的Win32 Windows 95应用程序都不能在Win32 Windows 2000下运行。我们愿意尝试与源代码兼容-*“您可以简单地使用更新的头重新编译” *。上面的代码重新编译为2000,在2000下将失败。
为什么文件系统路径长度完全没有限制?工程权衡。FAT16有限制。FAT32有限制。NTFS有一个限制。ReFS有一个限制。VFS有一个限制。每个文件系统都有一个限制。在Windows 95中,文件系统(FAT16)可以支持的最长路径是256个字符。指定大于文件系统有效最大路径长度的“ MAX_PATH”常量既错误又愚蠢。
@IanBoyd当然,有更多程序依赖于文件名是8.3,或者指针的大小是2个字节,或者整数的范围是-32768到32767,比这更多吗?
@IanBoyd完全正确.因此,重新编译使用此API以便它们可以处理更长路径名的程序是一样的.因此,MS决定不改变这一特定常数是没有意义的.
文件路径长度的问题和可能的解决方案在DotNetRocks情节中进行了讨论。值得一听:http://www.dotnetrocks.com/?show=1320

2> softveda..:

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

从.Net BCL团队博客的详细解释.
一个小的摘录突出了长路径的问题

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


很公平,但这意味着你必须在很多地方使用P/Invoke,在我看来,这会降低.Net代码的可移植性.如果我想保持单声道兼容性怎么办?
这应该是选择的答案.实际上回答用户提出的问题,为什么存在此限制并提供解决方法.提升可见度
@Mas你想要的"修复"完全回到了Windows XP.调用其API的unicode版本将允许您访问"扩展路径".我相信explorer会自动处理这个问题.这是一个支持它的功能 - http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx.

3> Ian Boyd..:

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

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

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

请考虑以下正确的代码:

WIN32_FIND_DATA findData;

FindFirstFile("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上运行.这就是向后兼容性所带来的.

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

但他们也必须不破坏现有的用户应用程序.绝大多数应用程序使用shell api进行文件工作.每个人只需要打电话FindFirstFile/ FindNextFile并且每天打电话.


向后兼容性很好.但我认为今天避免这种(通常是非常讨厌的)问题比支持Windows 3.1应用程序更重要.有多少人遇到长路径的问题?有多少人还在使用Windows 3.1应用程序?他们甚至取消了对Windows XP的支持.那么他们为什么不公布一下,从Windows [x]和后来的应用程序中假设不会有超过260个字符的路径,当它们遇到一条长路径时,它们将无法正常工作?我们的速度限制也不考虑车厢.
@JosiahKeller如果确实如此,它将破坏最初为该方法定义的合同,这样做可能会覆盖非预期的内存,并且可能会打开一个安全漏洞.解决这个问题的唯一方法是提供一个新的改进API(比如Unicode感知变体),并希望*每个人使用更新的API重新编译/重新发布所有应用程序.
@Ryios我认为现有的Windows应用程序不能在Linux上运行。
@JuSchu这不仅仅是Windows 3.1应用程序.今天使用正确的API编写的应用程序将无法运行.
@TheincredibleJan MSDN。[文档创建合同,这就是为什么您需要非常仔细地记录文档的原因](https://blogs.msdn.microsoft.com/oldnewthing/20150508-00/?p=44904)。

4> Root Loop..:

从Windows 10.您可以通过修改注册表项来消除限制.

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

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


    
        true
    


遗憾的是,即使在最新版本的Win10中,文件资源管理器本身仍然存在处理长路径名称的问题.甚至上下文菜单中的"复制为路径"也无法按预期工作; 它只复制前260个字符.你无法创建文件夹,复制/移动/打开文件......让我想知道这个变化有什么意义.

5> jonchang..:

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

subst x: \path\to\long\folder



6> JDiMatteo..:

处理路径限制的一种方法是使用符号链接缩短路径条目.

例如:

    创建一个C:\p目录以保持到长路径的短链接

    mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo

    添加C:\p\foo到您的路径而不是长路径


不必先创建目录,因此不需要步骤1.
这个技巧并不总是有效,因为许多应用程序试图解析链接

7> MovGP0..:

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

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

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

组策略编辑器



8> Conrad..:

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

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


@rubenvb我敢肯定,如果不是Windows的所有功能,大多数都可以在注册表中禁用,所以\\ _(ツ)_ /¯

9> Priidu Neemr..:

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

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

他们的SourceForge页面上的更多细节在这里:

"NTFS实际上可以支持最多32,000个字符的路径名."

7-zip也支持这么长的名字.

但它在SFX代码中被禁用.有些用户不喜欢长路径,因为他们不了解如何使用它们.这就是我在SFX代码中禁用它的原因.

和发行说明:

9.32 alpha 2013-12-01

改进了对长度超过260个字符的文件路径名的支持.

4.44 beta 2007-01-20

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

重要说明:为使其正常工作,您需要直接在7zip "提取"对话框中指定目标路径,而不是将文件拖放到目标文件夹中.否则,"Temp"文件夹将用作临时缓存,一旦Windows资源管理器开始将文件移动到"最终安放位置",您将跳转到相同的260 char限制.有关详细信息,请参阅对此问题的回复.


我错了,7zip和WinRAR确实提取了所有的文件夹和文件.只是Windows中文件夹的属性仅报告不违反限制的文件夹和文件的数量.就好像Windows资源管理器在达到最大路径时不会更深入地发现文件夹.

10> Sergey Dryga..:

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

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

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有