我在不合时宜的时刻曾多次反对这个问题:
为什么存在此限制?
为什么还没有删除它?
你如何应对路径限制? ......而且,切换到Linux或Mac OS X不是这个问题的有效答案;)
答案 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
的一面以允许更长的路径。为什么没有删除限制?
通过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)
应对路径限制的一种方法是使用符号链接缩短路径条目。
例如:
C:\p
目录以保留到长路径的短链接mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
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代码中禁用它。
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
中使用组策略:
答案 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,它可以使它们使用长路径(虽然我没有测试过)