我有几次在不合时宜的时候遇到过这个问题:

尝试在具有深度路径的开源Java项目上工作 在源代码控制中存储深度fitness wiki树 试图使用Bazaar导入源代码控制树时出错

为什么会有这个限制?

为什么它还没有被移除?

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


当前回答

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

. net BCL团队博客中关于漫长路径的详细解释。 一个小节选强调了长路径的问题

Another concern is inconsistent behavior that would result by exposing long path support. Long paths with the \\?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs. For example, LoadLibrary, which maps a module into the address of the calling process, fails if the file name is longer than MAX_PATH. So this means MoveFile will let you move a DLL to a location such that its path is longer than 260 characters, but when you try to load the DLL, it would fail. There are similar examples throughout the Windows APIs; some workarounds exist, but they are on a case-by-case basis.

其他回答

您可以将文件夹作为驱动器挂载。从命令行,如果你有一个路径C:\path\to\long\文件夹,你可以将它映射到驱动器号X:使用:

subst x: \path\to\long\folder

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

例如:

创建一个C:\p目录,将短链接保存到长路径 mklink /J C:\p\foo C:\一些\疯狂\长\路径\foo 将C:\p\foo添加到您的路径中,而不是长路径

问题是为什么这种限制仍然存在。当然,现代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,并称之为一天。

另一种处理方法是使用Cygwin,这取决于您想对文件做什么(即Cygwin命令是否适合您的需要)

例如,它允许复制、移动或重命名连Windows资源管理器都做不到的文件。当然,也可以处理它们的内容,如md5sum、grep、gzip等。

此外,对于你正在编写的程序,你可以将它们链接到Cygwin DLL,这将使它们能够使用长路径(我还没有测试这个)

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

Maximum Path Length Limitation In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)

现在我们看到它是1+2+256+1或[drive][:\][path][null] = 260。从DOS时代开始,人们可以假设256是一个合理的固定字符串长度。回到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的内存足够了。