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

6

我希望在Windows系统中访问一些很长的UNC路径。我知道需要使用前缀"\\?\UNC\"(如果你转义斜杠,则为"\\\\?\\UNC\\")。这个方法可以顺利地工作:

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

然而,使用相对路径似乎会失败:

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'

这可能是Python的一个bug,还是我的代码有问题?另外,一种解决方法是os.stat(os.path.abspath('aaa\\bbb.txt'))
1个回答

5
在Windows 10中,您可以通过在"HKLM\System\CurrentControlSet\Control\FileSystem"中设置名为"LongPathsEnabled"的DWORD来启用系统的长路径支持。这使得声明支持长路径的应用程序可以使用内核支持的最大路径长度(约32760个字符,取决于最终解析的路径),甚至不需要"\\?\"前缀。Python 3.6+已经被证明支持长路径。
话虽如此,在Windows 10之前,工作目录和相对路径不能超过MAX_PATH(260)个字符,这包括尾部反斜杠和NUL终止符。当前的文档在这一点上存在误导。显然,有人在SetCurrentDirectory的文档中添加了免责声明"将此限制扩展到32,767个宽字符..."。不,没有扩展这个限制。以下是2016年左右的情况。
进程的当前工作目录是DOS路径,而不是本机内核路径(*)。DOS路径是任何非Unicode路径,或使用正斜杠、DOS设备(例如逻辑驱动器字母、CON、NUL等)或UNC语法的路径。DOS路径必须由ntdll.dll中的运行时库函数转换为本机路径。如果长路径支持不可用,则此隐式转换最多限制为MAX_PATH个字符。
解决这个问题需要使用以"\\?\"前缀开头的完全限定的Unicode路径。这个前缀告诉运行时库绕过路径转换。相反,它只是用内核的"??\"虚拟目录替换了"\\?\"前缀,而路径最终解析为一个真正的NT设备(例如"\\?\UNC"=>"\??\UNC"=>"\Device\Mup")。
(*) 内核命名空间对于所有内核对象都使用单根树,而不仅仅是设备对象。它还有一种更可靠的处理相对路径的方法;请参阅OBJECT_ATTRIBUTESRootDirectory字段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接