Phy*_*ser 5 python windows unicode filenames utf-8
我有一个 PHP 脚本,可以在目录中创建文件列表,但是,PHP 只能看到英文文件名,而完全忽略其他语言(例如俄语或亚洲语言)的文件名。
\n\n经过大量努力,我找到了唯一适合我的解决方案 - 使用 python 脚本将文件重命名为 UTF8,以便 PHP 脚本可以在之后处理它们。
\n\n(PHP处理完文件后,我将文件重命名为英文,不将它们保留为UTF8)。
\n\n我使用了以下 python 脚本,效果很好:
\n\nimport sys\nimport os\nimport glob\nimport ntpath\nfrom random import randint\n\nfor infile in glob.glob( os.path.join('C:\\\\MyFiles', u'*') ):\n if os.path.isfile(infile):\n infile_utf8 = infile.encode('utf8')\n os.rename(infile, infile_utf8)\nRun Code Online (Sandbox Code Playgroud)\n\n问题是它还会转换已经采用 UTF8 格式的文件名。我需要一种方法来跳过转换,以防文件名已经是 UTF8。
\n\n我正在尝试这个 python 脚本:
\n\nfor infile in glob.glob( os.path.join('C:\\\\MyFiles', u'*') ):\n if os.path.isfile(infile):\n try:\n infile.decode('UTF-8', 'strict')\n except UnicodeDecodeError:\n infile_utf8 = infile.encode('utf8')\n os.rename(infile, infile_utf8) \nRun Code Online (Sandbox Code Playgroud)\n\n但是,如果文件名已经是 utf8 格式,我会收到致命错误:
\n\nUnicodeDecodeError: 'ascii' codec can't decode characters in position 18-20\nordinal not in range(128)\nRun Code Online (Sandbox Code Playgroud)\n\n我还尝试了另一种方法,同样不起作用:
\n\nfor infile in glob.glob( os.path.join('C:\\\\MyFiles', u'*') ):\n if os.path.isfile(infile):\n try:\n tmpstr = str(infile)\n except UnicodeDecodeError:\n infile_utf8 = infile.encode('utf8')\n os.rename(infile, infile_utf8) \nRun Code Online (Sandbox Code Playgroud)\n\n我得到了与以前完全相同的错误。
\n\n有任何想法吗?
\n\nPython对我来说非常陌生,即使是一个简单的脚本对我来说调试也是一个巨大的努力,所以请写一个明确的答案(即代码)。我没有能力测试可能有效或无效的一般想法。谢谢。
\n\n文件名示例:
\n\n hello.txt\n \xe4\xbd\xa0\xe5\xa5\xbd.txt\n \xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94.html\n cha\xcd\x80o.doc\nRun Code Online (Sandbox Code Playgroud)\n
我认为您混淆了术语并做出了一些错误的假设。AFAIK,PHP 可以打开任何编码类型的文件名 - PHP 对于编码类型非常不可知。
\n你还不清楚你想要实现什么,因为 UTF-8 != English ,示例外国文件名可以用多种方式编码,但不能用 ASCII 英语!您能否解释一下现有的 UTF-8 文件是什么样子以及非 UTF-8 文件是什么?
\n更让您困惑的是,在 Windows 下,文件名透明地存储为 UTF-16。\n因此,您不应尝试将文件名编码为 UTF-8。相反,您应该使用 Unicode 字符串并允许 Python 进行正确的转换。(也不要使用 UTF-16 进行编码!)
\n请进一步澄清您的问题。
\n更新:
\n我现在明白你的 PHP 问题了。http://evertpot.com/filesystem-encoding-and-php/告诉我们非拉丁字符在 PHP+Windows 中很麻烦。似乎只能看到和打开由 Windows 1252 字符集字符组成的文件。
\n您面临的挑战是将文件名转换为与 Windows 1252 兼容。正如您在问题中所述,最好不要重命名已经兼容的文件。我已将您的尝试修改为:
\nimport os\nfrom glob import glob\nimport shutil\nimport urllib\n\nfiles = glob(u\'*.txt\')\nfor my_file in files:\n try:\n print "File %s" % my_file\n except UnicodeEncodeError:\n print "File (escaped): %s" % my_file.encode("unicode_escape")\n new_name = my_file\n try:\n my_file.encode("cp1252" , "strict")\n print " Name unchanged. Copying anyway"\n except UnicodeEncodeError:\n print " Can not convert to cp1252"\n utf_8_name = my_file.encode("UTF-8")\n new_name = urllib.quote(utf_8_name )\n print " New name: (%% encoded): %s" % new_name\n \n shutil.copy2(my_file, os.path.join("fixed", new_name))\nRun Code Online (Sandbox Code Playgroud)\n分解:
\n打印文件名。默认情况下,Windows shell 仅显示本地 DOS 代码页中的结果。例如,我的 shell 可以显示,\xc3\xbc.txt但\xe2\x82\xac.txt显示为?.txt. 因此,您需要小心Python抛出异常,因为它无法正确打印。此代码尝试打印 Unicode 版本,但改为打印 Unicode 代码点转义。
尝试将字符串编码为 Windows-1252。如果有效,则文件名没问题
\n否则:将文件名转换为 UTF-8,然后对其进行百分比编码。这样,文件名保持唯一,您可以在 PHP 中反转此过程。
\n将文件复制到新的/已验证的文件。
\n例如,\xe4\xbd\xa0\xe5\xa5\xbd.txt 变为 %E4%BD%A0%E5%A5%BD.txt
\n| 归档时间: |
|
| 查看次数: |
12140 次 |
| 最近记录: |