我想在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 中的一个错误,还是我的代码错误?
旁注 - 解决方法是os.stat(os.path.abspath('aaa\bbb.txt'))
.
在 Windows 10 中,您可以通过在"HKLM\System\CurrentControlSet\Control\FileSystem"中设置名为"LongPathsEnabled"的 DWORD 来启用对系统的长路径支持。这允许在其清单中声明支持长路径的应用程序使用内核支持的最大路径长度(大约 32,760 个字符,具体取决于最终解析的路径),甚至不需要"\\?\"前缀。Python 3.6+ 体现在支持长路径。
也就是说,在 Windows 10 之前,工作目录和相对路径不能超过MAX_PATH
(260) 个字符,其中包括尾随反斜杠和 NUL 终止符。当前的文档在这一点上具有误导性。显然有人添加了免责声明"将此限制扩展到 32,767 个宽字符......"到文档进行SetCurrentDirectory
.不,没有延长限制。这是它在2016年左右说的。
进程的当前工作目录是 DOS 路径,而不是本机内核路径 (*)。DOS 路径是任何非 Unicode 的路径,或使用正斜杠、DOS 设备(例如逻辑驱动器号、CON、NUL 等)或 UNC 语法。DOS 路径必须由 ntdll.dll 中的运行时库函数转换为本机路径。如果长路径支持不可用,则此隐式转换最多限制为MAX_PATH
个字符。
解决此问题需要使用以"\\?\"前缀开头的完全限定的 Unicode 路径。此前缀告知运行时库绕过路径转换。相反,它只是将"\\?\"前缀替换为内核的"\??\" DOS 设备链接的虚拟目录,并且路径最终解析为真正的 NT 设备(例如 "\\?\UNC" => "\??\UNC" => "\Device\Mup")。
(*) 内核命名空间对所有内核对象(而不仅仅是设备对象)使用单根树。它还具有更可靠的处理相对路径的方法;请参阅OBJECT_ATTRIBUTES
的RootDirectory
字段。