Windows 上 python 的长路径 - os.stat() 对于相对路径失败? [英] Long paths for python on windows - os.stat() fails for relative paths?

查看:82
本文介绍了Windows 上 python 的长路径 - os.stat() 对于相对路径失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Windows 上访问一些长的 UNC 路径.我知道我需要使用 "\\?\UNC\" 前缀(它是 "\\\\?\\UNC\\" 如果您转义斜线).效果很好:

I want to access some long UNC paths on Windows. I know that I need to use the "\\?\UNC\" prefix (which is "\\\\?\\UNC\\" if you escape the slashes). That works fine:

<代码> os.stat( '\\\\ \\?UNC \\ server.example.com \\该\\具有\\长\\路径\\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.txt')# 有效,返回 os.stat_result

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

However, it seems to fail with a relative path:

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 中的错误,还是我的代码有误?

Might this be a bug in Python, or is my code wrong?

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

Sidenote - a workaround is os.stat(os.path.abspath('aaa\\bbb.txt')).

推荐答案

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

In Windows 10, you can enable long-path support for the system by setting a DWORD named "LongPathsEnabled" in "HKLM\System\CurrentControlSet\Control\FileSystem". This allows applications that declare support for long paths in their manifest to use the maximum path length that's supported by the kernel (about 32,760 characters, depending on the final resolved path), without even requiring the "\\?\" prefix. Python 3.6+ is manifested to support long paths.

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

That said, prior to Windows 10, the working directory and relative paths cannot exceed MAX_PATH (260) characters, which includes the trailing backslash and NUL terminator. The current documentation is misleading on this point. Apparently someone added the disclaimer "to extend this limit to 32,767 wide characters..." to the docs for SetCurrentDirectory. No, there's no extending the limit. Here's what it said circa 2016.

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

The current working directory of a process is a DOS path, as opposed to a native kernel path (*). A DOS path is any path that's non-Unicode, or uses forward slashes, DOS devices (e.g. logical drive letters, CON, NUL, etc), or UNC syntax. DOS paths have to be translated to native paths by runtime-library functions in ntdll.dll. If long-path support isn't available, this implicit translation is limited to at most MAX_PATH characters.

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

Working around this requires using a fully-qualified Unicode path that begins with the "\\?\" prefix. This prefix tells the runtime-library to bypass path translation. Instead it simply replaces the "\\?\" prefix with the kernel's "\??\" virtual directory for DOS device links, and the path ultimately resolves to a real NT device (e.g. "\\?\UNC" => "\??\UNC" => "\Device\Mup").

(*) 内核命名空间对所有内核对象使用单根树,而不仅仅是设备对象.它还具有更可靠的处理相对路径的方式;请参阅 RootDirectory 字段="nofollow noreferrer">OBJECT_ATTRIBUTES.

(*) The kernel namespace uses a singly-rooted tree for all kernel objects, not just device objects. It also has a more reliable way of handling relative paths; see the RootDirectory field of OBJECT_ATTRIBUTES.

这篇关于Windows 上 python 的长路径 - os.stat() 对于相对路径失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆