Windows 上 python 的长路径 - os.stat() 对于相对路径失败?

pia*_*mes 6 python windows path

我想访问 Windows 上的一些长 UNC 路径。我知道我需要使用"\\?\UNC\"前缀(如果"\\\\?\\UNC\\"你转义斜杠)。效果很好:

os.stat('\\\\?\\UNC\\server.example.com\\that\\has\\long\\path\\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.txt')
# works, returns os.stat_result
Run Code Online (Sandbox Code Playgroud)

但是,相对路径似乎失败了:

os.chdir('\\\\?\\UNC\\server.example.com\\that\\has\\long\\path')
os.getcwd()
# returns '\\\\?\\UNC\\server.example.com\\that\\has\\long\\path'
os.stat('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.txt')
# fails with [WinError 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.txt'
Run Code Online (Sandbox Code Playgroud)

这可能是Python中的一个错误,还是我的代码错误?

旁注 - 解决方法是os.stat(os.path.abspath('aaa\\bbb.txt'))

Ery*_*Sun 5

在 Windows 10 中,您可以通过在“HKLM\System\CurrentControlSet\Control\FileSystem”中设置名为“LongPathsEnabled”的 DWORD 来启用系统的长路径支持。这允许在清单中声明支持长路径的应用程序使用内核支持的最大路径长度(大约 32,760 个字符,具体取决于最终解析的路径),甚至不需要“\\?\”前缀。Python 3.6+ 被证明支持长路径。

也就是说,在 Windows 10 之前,工作目录和相对路径不能超过MAX_PATH(260) 个字符,其中包括尾部反斜杠和 NUL 终止符。当前的文档在这一点上具有误导性。显然有人在SetCurrentDirectory. 不,不能延长限制。这是2016 年左右的说法。

进程的当前工作目录是 DOS 路径,而不是本机内核路径 (*)。DOS 路径是非 Unicode 的任何路径,或者使用正斜杠、DOS 设备(例如逻辑驱动器号、CON、NUL 等)或 UNC 语法。DOS 路径必须通过 ntdll.dll 中的运行时库函数转换为本机路径。如果长路径支持不可用,则此隐式转换仅限于最多MAX_PATH字符。

解决此问题需要使用以“\\?\”前缀开头的完全限定的 Unicode 路径。此前缀告诉运行时库绕过路径转换。相反,它只是将“\\?\”前缀替换为内核的“\??\”虚拟目录以用于 DOS 设备链接,并且该路径最终解析为真正的 NT 设备(例如“\\?\UNC”=>“ \??\UNC" => "\Device\Mup")。


(*) 内核命名空间对所有内核对象(而不仅仅是设备对象)使用单根树。它还具有更可靠的处理相对路径的方式;参见RootDirectory的领域OBJECT_ATTRIBUTES