Python 3.10:FileNotFoundError - 具有 Unicode 字符的现有路径

Python 3.10: FileNotFoundError - Existing Path With Unicode Characters

问题陈述:

在输入目录和输出目录之间自动复制文件时,我的程序在包含 unicode(很可能是韩语)字符的路径上失败。

整个脚本在以下位置公开可用:This Link

导致错误的文件也是公开的:File That Causes the Error

失败的代码的特定部分似乎是:

for root, _, filenames in os.walk(maybe_dir):
    for file in filenames:
        # Prepare relative paths:
        relative_dir = os.path.relpath(root, maybe_dir)
        relative_file = os.path.join(relative_dir, file)

        # Get unique filename:
        unique_filename = uuid.uuid4().hex
        unique_filename_with_ext = unique_filename + file_extension
        new_path_and_filename = os.path.join(
            full_output_path, unique_filename_with_ext
        )

        current_file = os.path.abspath(os.path.join(root, file))

        # Copying files:
        shutil.copy(current_file, new_path_and_filename)

错误:

Traceback (most recent call last):
  File "F:\Projects\SC2DatasetPreparator\src\directory_flattener.py", line 96, in <module>      
    directory_flattener(
  File "F:\Projects\SC2DatasetPreparator\src\directory_flattener.py", line 60, in directory_flattener
    shutil.copy(current_file, new_path_and_filename)
  File "D:\Programs\Python3_10\lib\shutil.py", line 417, in copy
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "D:\Programs\Python3_10\lib\shutil.py", line 254, in copyfile
    with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: 'F:\Projects\SC2DatasetPreparator\processing\directory_flattener\input\2017_IEM_XI_World_Championship_Katowice\IEM XI - World Championship - StarCraft II Replays\RO24\Group A\Solar Vs herO\Ùë¦ý+ñÝü¼ ý×¼Û¦£Ù¦£ ýºÇÛÁ¼ - ÝåáÙäêÙ¿+Ýè© (Û¦ÁÝùêýØÿ ý£áýé¦) (2) Solar vs Hero game 1.SC2Replay'

错误本身是意外的,因为我使用的是绝对路径,并且该脚本在该特定文件失败之前适用于其他 6 个目录。

路径明确存在,可以手动访问:

尝试重现错误的步骤如下:

  1. 克隆存储库:Branch 1.1.0_testing
  2. File That Causes the Error 放入 ./processing/directory_flattener/input/test_dir
  3. 运行 脚本

结束语:

似乎该脚本之前在 Python 3.7 上运行,因为我已经验证了在更新到 Python 3.10 之前收到的输出以及在使用 unicode 创建的文件的目录映射中存在路径中的字符:

{
"ce2f4610891e472190a0852c617b35e8": "RO24\Group A\Solar Vs herO\\u00d9\u00eb\u00a6\u00fd+\u00f1\u00dd\u00fc\u00bc \u00fd\u00d7\u00bc\u00db\u00a6\u00a3\u00d9\u00a6\u00a3 \u00fd\u00ba\u00c7\u00db\u00c1\u00bc - \u00dd\u00e5\u00e1\u00d9\u00e4\u00ea\u00d9\u00bf+\u00dd\u00e8\u00a9 (\u00db\u00a6\u00c1\u00dd\u00f9\u00ea\u00fd\u00d8\u00ff \u00fd\u00a3\u00e1\u00fd\u00e9\u00a6) (2) Solar vs Hero game 1.SC2Replay",
"dcc82d633910479c95d06ef418fcf2e0": "RO24\Group A\Solar Vs herO\\u00fd\u00fb\u00a6\u00d9\u00a6\u00e4\u00fd\u00e4\u00f1 \u00d9\u00aa\u00bc\u00dd\u00f6\u00e4 - \u00d9\u00d7\u00ff\u00d9\u00ec\u00f6 Solar vs Hero game 2.SC2Replay", 
}

在寻找答案时,我只是在 Python 2 中偶然发现了类似的问题,其中建议使用 .decode() 方法作为解决方案。采取这些措施并没有帮助解决问题。

此错误的原因是 Maximum Path Length Limitation 限制了在 Windows 上使用超过 260 个字符的路径的能力。

通过向用于访问和复制文件的路径添加前缀 "\?\" 修复了错误。

这意味着更改了以下代码行:

current_file = os.path.abspath(os.path.join(root, file))

进入这个:

current_file = "\\?\" + os.path.abspath(os.path.join(root, file))