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

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

为什么会有这个限制?

为什么它还没有被移除?

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


当前回答

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

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

另一个版本是在计算机配置/管理模板/系统/文件系统中使用组策略:

其他回答

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

Tip Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. However, you must opt-in to the new behavior. A registry key allows you to enable or disable the new long path behavior. To enable long path behavior set the registry key at HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD). The key's value will be cached by the system (per process) after the first call to an affected Win32 file or directory function (list follows). The registry key will not be reloaded during the lifetime of the process. In order for all apps on the system to recognize the value of the key, a reboot might be required because some processes may have started before the key was set. The registry key can also be controlled via Group Policy at Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. You can also enable the new long path behavior per app via the manifest: <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>

至于为什么这个问题仍然存在——微软并不认为它是一个优先级,并且认为向后兼容性比改进他们的操作系统更重要(至少在这种情况下)。

我使用的一种变通方法是为路径中的目录使用“短名称”,而不是使用标准的、人类可读的版本。例如,对于C:\Program Files\,我会使用C:\PROGRA~1\你可以使用dir /x找到简短的等价名称。

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

subst x: \path\to\long\folder

引用这篇文章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的内存足够了。

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