【问题标题】:Convert windows-1251 directory names to unicode (using Python)将 windows-1251 目录名称转换为 unicode(使用 Python)
【发布时间】:2015-10-08 12:28:28
【问题描述】:

我使用 php 脚本创建目录,使用从站点 (utf-8) 获取的单词(类别名称),但是当我创建这些目录时,我看到有不可读的字符而不是真实的字。

Windows 下的 AFAIK PHP 在 cp1251 语言环境下工作,不能在 utf-8 文件名/目录名下工作。

所以问题是,是否可以使用 Python 遍历所有目录并将它们重命名为 utf-8 字符集?

看起来那段代码有效,现在我只需要递归遍历目录并重命名它们。

basedir = "C:\\Users\\alex\\Desktop\\1\\save"
dirs = os.listdir(basedir)
for fn in dirs:
    print fn
    nn = fn.decode('utf-8')
    os.rename(os.path.join(basedir,fn), os.path.join(basedir,nn))

【问题讨论】:

  • 使用 Unicode 文字:os.path.expanduser(ur"~\Desktop\1\save"),获取 Unicode 文件名。

标签: php python unicode utf-8


【解决方案1】:

如果 php 将您的 utf-8 文件名保存为 cp1251,那么您可以将它们重新编码:

>>> correct_filename = u"торт.txt"
>>> mojibake = correct_filename.encode('utf-8').decode('cp1251') # WRONG
>>> print(mojibake) # if you see this;
торт.txt
>>> print(mojibake.encode('cp1251').decode('utf-8')) # recode
торт.txt

在 Windows 上始终使用 Unicode 类型的文件名。

要重命名给定目录中的所有 .txt 文件:

#!/usr/bin/env python2
import os
from glob import glob

dirpath = os.path.expanduser(ur"~\Desktop\1\save")
for mojibake_path in glob(os.path.join(dirpath, '*.txt')):
    path = mojibake_path.encode('cp1251').decode('utf-8')
    os.rename(mojibake_path, path)

注意:dirpath 是一个 Unicode 字符串。

【讨论】:

  • 为什么windows使用windows-1251时文件名必须使用unicode类型?
  • @IvanPetrov:如果您在 Python 中处理文本,则应该使用 Unicode 类型。文件名是 Windows 上的文本(它为它们提供 Unicode API)。在这种情况下无关紧要(所有(无效)构造的文件名都有 cp1251 范围内的字符),但通常 Unicode 支持大约一百万个字符,而 cp1251 仅支持 256 个。
  • 那么,最后,windows 对文件名使用什么编码?是 unicode (utf-16) 还是 windows-1251?
  • @IvanPetrov:Unicode 在这里表示type(text) == unicode。它与 utf-16 无关。您需要知道的是,如果您传递 Unicode 文件名;你在 Windows 上得到一个 Unicode 文件名。 unicode 是一个抽象 -- Python 可能在不同的 Python 版本/构建上使用不同的内部表示 -- 你不应该关心它在 Python 或 Windows 内部是如何表示的(除了一些边缘情况狭窄的 Python 构建在 Python 2) 中。
【解决方案2】:

有几点需要澄清:

  • UTF-8 是一种编码,而不是字符集。该字符集称为 Unicode。 ? 是该字符集中的字符 128169。

  • 字符串"?.txt" 包含5 个字符。您可以使用 UTF-8 或 UTF-16 等编码将这些字符编码为 bytes。计算机存储字节,因此程序必须使用其中一种编码在内部表示该字符串。

  • 因此,没有“将目录重命名为 Unicode 字符集”之类的事情。文件名?.txt 就是这 5 个字符,无论操作系统如何将这些字符存储在磁盘上。

问题出在 PHP 本身。在 Windows 上,PHP 在本地 ANSI 代码页中对字符串进行内部编码。该代码页可能无法对字符 ? 进行编码,因此 PHP 无法在内部表示此字符串。因此,您永远无法在 PHP 中访问文件 ?.txt。唯一的解决方法是使用特殊模块来访问这些文件。见How to open file in PHP that has unicode characters in its name?

【讨论】:

  • 感谢您的澄清。现在我试图理解 cp 和编码的东西。我还看到,为了正确表示目录名称,我需要将它们转换为 windows-1251 编码。我做了一些搜索并编写了一些代码来使用 python 重命名我的目录(我现在会更新我的帖子)。所以问题解决了一半。唯一的问题是我很好奇 .decode('utf-8') 方法是如何工作的,因为我没有指定要转换的编码。
  • 是的,在 PHP 中这可能是正确的。根据 Sebastian 的回答,您可以使用 Python 修复文件名,但请注意,这些文件将不再可以从 PHP 访问。
  • @IvanPetrov:这些文件可以通过 PHP(以及任何其他方式)访问。我的代码修复了 mojibake,例如 торт,以获取 торт
  • @J.F.Sebastian 这是 Windows 版本 PHP 的已知限制。如果您的代码页不包含西里尔字母,则 PHP 无法打开名为 торт.txt 的文件。
  • @J.F.Sebastian 好点。另外,感谢您的编辑——我下次会记住这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-06
  • 2010-09-30
  • 2011-11-05
  • 1970-01-01
  • 2012-02-22
  • 2017-07-21
  • 2010-11-06
相关资源
最近更新 更多