Python3在Windows系统上对长路径的支持

Windows XP及之后的版本

maximum-path-length-limitation中提到,可以将路径转换为extended-length path再传入相关API。具体转换方式为

  1. 将路径中的斜杠(/)替换为反斜杠(\)
  2. 在路径前增加前缀\\?\
  3. 如果是UNC路径,需要删除开头的\\,并增加\\?\UNC\前缀。如\\server\share需要转换为\\?\UNC\server\share
    该方法最长可支持32767左右的路径长度。
    可以将extended-length path作为路径直接传入open函数来打开文件。但os.path.walk、os.path.join等路径相关的函数在处理extended-length path时会和预期的效果不太一样。建议在代码中始终传递原始路径,自己封装open函数,将filename参数转换为extended-length path并传入真正的open函数中。

Windows 10 1607及之后的版本

enable-long-paths-in-windows-10-version-1607-and-later中提到,Windows 10 1607及之后的版本, 在满足注册表或组策略中启用对长路径的支持,且应用程序本身的Mainfset中标识支持长路径的前提下,应用程序可直接打开拥有长路径的文件。
Python3.6(changlist)开始,可以用这种方式支持长路径。代码中可以直接通过open(long_path)的方式读写拥有长路径的文件。

PyInstaller相关

使用extended-length path方案的代码,在使用PyInstaller生成可执行程序后依然可以正常工作
而使用第二种方案的代码,在使用PyInstaller(截止到v3.5)生成可执行程序之后,需要修改Mainfset才能正常工作。
Mainfset本质上是一个xml描述文件。描述可执行程序或动态库的元数据。包括依赖的动态库版本、支持的特性等。可以作为资源文件内嵌,也可以是独立的文件。
使用方案二支持长路径,要求应用程序的Mainfset中包含 longPathAware 元素
Python3.6及之后的python.exe,内嵌Mainfset已经包含longPathAware元素。而PyInstaller在Windows上生成的程序,Mainfset在独立的.mainfset文件中,且内部没有包含longPathAware元素。需要修改.mainfset文件,增加元素,才能正常工作