来自 Python 的 Win32 长路径 [英] Win32 long paths from Python

查看:24
本文介绍了来自 Python 的 Win32 长路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这个问题是关于新支持的win32 long路径(自 Windows 10 Version 1607, Build 14352 起可用)而不是关于以 \\?\ 开头的扩展 UNC 路径.

<小时>

我通过组策略启用了长路径支持并重新启动了我的电脑.我在注册表中检查 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\FileSystem\LongPathsEnabledHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled 都设置为 1.

然后我打开了一个 Python REPL 并尝试创建一个超过 260 个字符限制的目录,但失败了:

<预><代码>>>>导入操作系统>>>长目录名 = 'a' * 300>>>长目录名'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>>>os.makedirs(longdirname)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件c:\python27\lib\os.py",第 157 行,在 makedirs 中mkdir(名称,模式)WindowsError:[错误3]系统无法找到路径指定:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"[错误3]系统无法找到路径指定:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

我假设长路径支持不知何故在这里没有生效.这是为什么,我如何正确启用它以便它可以从 Python 脚本运行?

<小时>

更新:我还尝试通过 pywin32 直接调用 Win32 API 函数,该函数声明 在其文档中n 它应该支持长路径,但再次失败:

<预><代码>>>>导入 win32 文件>>>长名称 = 'a' * 300>>>win32file.CreateDirectoryW(longname, None)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中错误:(3,'CreateDirectoryW','系统找不到指定的路径.')(3, 'CreateDirectoryW', '系统找不到指定的路径.')

<小时>

更新 2:还尝试通过单个组件创建:

<预><代码>>>>对于范围内的 i (1, 300):... win32file.CreateDirectoryW('a', None)... os.chdir('a')回溯(最近一次调用最后一次):文件<stdin>",第 2 行,在 <module>错误:(206,'CreateDirectoryW','文件名或扩展名太长.')(206, 'CreateDirectoryW', '文件名或扩展名太长.')

(os.makedirs 在这种情况下也不起作用)

<小时>

更新 3:以下批处理脚本不会失败:

@echo offsetlocal enableextensions enabledelayedexpansion推设置/一个计数= 1for/L %%i in (1,1,300) 做 (目录光盘回声%%i)本地端弹出

所以我假设这在某种程度上与 Python 相关.

解决方案

解决方案既简单又有些令人失望:3.6 之前的 Python 版本无法利用长路径.3.6 更改列表.

<块引用>

Windows 过去将路径长度限制为 260 个字符.这意味着比这更长的路径将无法解析并导致错误.

在最新版本的 Windows 中,此限制可以扩展到大约 32,000 个字符.您的管理员需要激活启用 Win32 长路径"组策略,或将注册表值 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled 设置为 1.

这允许 open() 函数、os 模块和大多数其他路径功能在使用字符串时接受和返回长度超过 260 个字符的路径.(在 Windows 上不推荐使用字节作为路径,并且在使用字节时此功能不可用.)

更改上述选项后,无需进一步配置.

在 3.6 版更改:在 Python 中启用了对长路径的支持.

为了证明它有效,我做了以下事情:

Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 位 (Intel)] on win32输入帮助"、版权"、信用"或许可"以获取更多信息.>>>导入操作系统>>>longdir = 'a' * 300>>>os.makedirs(longdir)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件C:\Users\tamas\AppData\Local\Programs\Python\Python36-32\lib\os.py",第 220 行,在 makedirs 中mkdir(名称,模式)OSERROR:[WinError 123]的文件名,目录名或卷标语法不正确:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">>>对于范围内的 i (1, 300):... os.mkdir('a')... os.chdir('a')...>>>len(os.getcwd())631>>>

第一个 makedirs 调用失败,因为单个组件仍然限制为 255 个字符.

Note: this question is about the newly supported win32 long paths (available since Windows 10 Version 1607, Build 14352) and not about extended UNC paths starting with \\?\.


I enabled long path support via a group policy and rebooted my PC. I checked in the registry that both HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\FileSystem\LongPathsEnabled and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled are set to 1.

Then I opened a Python REPL and tried to create a directory that will exceed the 260-char limit, but failed:

>>> import os

>>> longdirname = 'a' * 300

>>> longdirname
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

>>> os.makedirs(longdirname)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python27\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
[Error 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

I'm assuming that the long path support somehow didn't take effect here. Why is this and how can I properly enable it so that it works from Python scripts?


Update: I also tried directly calling a Win32 API function via pywin32 that claims in its documentation that it should support long paths, but failed again:

>>> import win32file

>>> longname = 'a' * 300

>>> win32file.CreateDirectoryW(longname, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
error: (3, 'CreateDirectoryW', 'The system cannot find the path specified.')
(3, 'CreateDirectoryW', 'The system cannot find the path specified.')


Update 2: Also tried creating via individual components:

>>> for i in range(1, 300):
...     win32file.CreateDirectoryW('a', None)
...     os.chdir('a')
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
error: (206, 'CreateDirectoryW', 'The filename or extension is too long.')
(206, 'CreateDirectoryW', 'The filename or extension is too long.')

(os.makedirs also won't work in this case)


Update 3: The following batch script will not fail:

@echo off

setlocal enableextensions enabledelayedexpansion

pushd

set /a count = 1
for /L %%i in (1,1,300) do (
  mkdir a
  cd a
  echo %%i
)
endlocal

popd

So I'm assuming that this is somehow related to Python then.

解决方案

The solution is both simple and somewhat disappointing: Python versions prior to 3.6 are not able to take advantage of long paths. 3.6 changelist.

Windows historically has limited path lengths to 260 characters. This meant that paths longer than this would not resolve and errors would result.

In the latest versions of Windows, this limitation can be expanded to approximately 32,000 characters. Your administrator will need to activate the "Enable Win32 long paths" group policy, or set the registry value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled to 1.

This allows the open() function, the os module and most other path functionality to accept and return paths longer than 260 characters when using strings. (Use of bytes as paths is deprecated on Windows, and this feature is not available when using bytes.)

After changing the above option, no further configuration is required.

Changed in version 3.6: Support for long paths was enabled in Python.

To prove that it works, I did the following:

Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> longdir = 'a' * 300
>>> os.makedirs(longdir)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\tamas\AppData\Local\Programs\Python\Python36-32\lib\os.py", line 220, in makedirs
    mkdir(name, mode)
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
>>> for i in range(1, 300):
...     os.mkdir('a')
...     os.chdir('a')
...
>>> len(os.getcwd())
631
>>>

The first makedirs call fails because individual components are still limited to 255 characters.

这篇关于来自 Python 的 Win32 长路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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