【问题标题】:Cannot Create Long Filename on Windows 10 & Python 3无法在 Windows 10 和 Python 3 上创建长文件名
【发布时间】:2020-05-06 04:59:45
【问题描述】:

在 Windows 10 Home 和 Python 3.6.6 上,我通过 setting it in the registryprefixing \\?\ 启用了长路径。我还关注了this answer 并确保路径使用\\ 而不是/,在unicode u' 中并且是绝对路径。我的文件名中没有非法字符。我的文件路径也比maximum total path length of 32,767 characters 小很多。

尽管执行了上述所有操作,但当我尝试创建长文件名时,我仍然得到OSError: [Errno 22] Invalid argument。我尝试了 3 种不同的方法来创建文件路径,如下面的output_filepath,但都不起作用:

# Long filename - Does not work
import os, pathlib
output_filepath = u'\\\\?\\' + os.path.join(os.path.dirname(os.path.realpath(__file__)), u"somereallylongname" * 30 + u".result")
# output_filepath = u'\\\\?\\C:\\Users\\Jarrett\\Downloads\\somereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongname\\x.x'
# output_filepath = r'\\?\C:\Users\Jarrett\Downloads\somereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongname\x.x'
print("filepath length = %s" % len(output_filepath))
print("filename length = %s" % len(os.path.basename(output_filepath)))
if not os.path.exists(os.path.dirname(output_filepath)): os.makedirs(os.path.dirname(output_filepath))
pathlib.Path(output_filepath).touch() # or open(output_filepath, 'a').close()
print("Wrote to " + output_filepath)

【问题讨论】:

  • Python 3 中的字符串是 unicode;无需使用 Python 2 中的 u 前缀。此外,如果您使用的是 Python 3.6+ 和 Windows 10,并且您已在注册表中启用长路径,则无需使用扩展路径 (即非规范化设备路径)在“\\?\”设备根路径中。您可以使用常规 DOS 路径。正如 Drake 所讨论的,问题在于文件系统的最大组件长度是根据其内部数据结构固定的,绝对没有什么可以改变这一点。
  • Windows API 本身具有类似的组件长度限制,该限制被嵌入到来自FindFirstFileW/FindNextFileW 的目录列表的结果中,由 Python 的 os.listdiros.scandir 在内部调用。 API 将目录列表中的名称限制为 MAX_PATH (260) 个字符。请注意,在这种情况下,他们重用了 MAX_PATH 常量,尽管目录列表中的名称不是路径。

标签: python python-3.x windows winapi python-3.6


【解决方案1】:

文件名组件(文件名中反斜杠之间的部分)太长,最大组件长度取决于GetVolumeInformation函数的lpMaximumComponentLength参数返回的值。

例如,对于支持长名称的 FAT 文件系统,该函数存储值 255。

尽量缩短文件名部分的长度,如:

import os, pathlib
output_filepath = u'\\\\?\\' + os.path.join(os.path.dirname(os.path.realpath(__file__)), u"somereallylongname" * 14 + u'\\' + u"somereallylongname" * 14 + u'\\' + u"somereallylongname" * 2 + u".result")
# output_filepath = u'\\\\?\\C:\\Users\\Jarrett\\Downloads\\somereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongname\\x.x'
# output_filepath = r'\\?\C:\Users\Jarrett\Downloads\somereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongnamesomereallylongname\x.x'
print(output_filepath)
print("filepath length = %s" % len(output_filepath))
print("filename length = %s" % len(os.path.basename(output_filepath)))
if not os.path.exists(os.path.dirname(output_filepath)): os.makedirs(os.path.dirname(output_filepath))
pathlib.Path(output_filepath).touch() # or open(output_filepath, 'a').close()
print("Wrote to " + output_filepath)

【讨论】:

  • 感谢您的回复。换句话说,您所说的是文件路径可以> 255,但文件名不能,因此错误?
  • 是的,根据您链接的最后一个文档,“...允许最大总路径长度为 32,767 个字符的扩展长度路径。这种类型的路径由分隔的组件组成通过反斜杠,每个反斜杠最多为GetVolumeInformation 函数的lpMaximumComponentLength 参数中返回的值(该值通常为 255 个字符)。 ..."
  • "但文件名不能",以及反斜杠之间的目录名。
  • 嗨,@jarrettyeo 这能回答你的问题吗?
猜你喜欢
  • 1970-01-01
  • 2017-09-30
  • 2021-11-08
  • 2013-08-25
  • 1970-01-01
  • 2020-04-10
  • 2020-02-19
  • 2011-09-01
  • 2019-05-19
相关资源
最近更新 更多