Python如何检查文件名是否在UTF8中?

我有一个PHP脚本,该脚本在目录中创建文件列表,但是,PHP仅能看到英语的文件名,而完全忽略其他语言(例如俄语或亚洲语言)的文件名.

经过大量的努力,我找到了唯一对我有用的解决方案-使用python脚本将文件重命名为UTF8,因此PHP脚本可以在此之后对其进行处理.

(在PHP完成文件处理之后,我将文件重命名为英语,而不是将它们保留在UTF8中).

我使用以下python脚本,效果很好:

import sys
import os
import glob
import ntpath
from random import randint

for infile in glob.glob( os.path.join('C:\\MyFiles', u'*') ):
    if os.path.isfile(infile):
      infile_utf8 = infile.encode('utf8')
      os.rename(infile, infile_utf8)

问题在于它还会转换UTF8中已经存在的文件名.如果文件名已经在UTF8中,我需要一种跳过转换的方法.

我正在尝试以下python脚本:

for infile in glob.glob( os.path.join('C:\\MyFiles', u'*') ):
    if os.path.isfile(infile):
      try:
        infile.decode('UTF-8', 'strict')
      except UnicodeDecodeError:
        infile_utf8 = infile.encode('utf8')
        os.rename(infile, infile_utf8)    

但是,如果文件名已经在utf8中,则会出现致命错误:

UnicodeDecodeError: 'ascii' codec can't decode characters in position 18-20
ordinal not in range(128)

我还尝试了另一种方法,但也没有用:

for infile in glob.glob( os.path.join('C:\\MyFiles', u'*') ):
    if os.path.isfile(infile):
      try:
        tmpstr = str(infile)
      except UnicodeDecodeError:
        infile_utf8 = infile.encode('utf8')
        os.rename(infile, infile_utf8)      

我得到了与以前完全相同的错误.

有任何想法吗?

Python对我来说是一个非常新的东西,即使调试一个简单的脚本也需要付出巨大的努力,因此请写一个明确的答案(即代码).我没有能力测试可能有用或无效的一般想法.谢谢.

文件名示例:

 hello.txt
 你好.txt
 안녕하세요.html
 chào.doc

解决方法:

我认为您在混淆术语并做出一些错误的假设. AFAIK,PHP可以打开任何编码类型的文件名-PHP与编码类型无关.

您还不确定要使用UTF-8来实现什么目标!==英语,并且示例外部文件名可以通过多种方式编码,但从来没有采用ASCII英文!您能否解释一下您认为现有UTF-8文件的外观以及非UTF-8文件的外观?

更令人困惑的是,在Windows下,文件名透明存储为UTF-16.
因此,您不应尝试将文件名编码为UTF-8.相反,您应该使用Unicode字符串,并允许Python进行正确的转换. (也不使用UTF-16编码!)

请进一步澄清您的问题.

更新:

我现在了解您的PHP问题. http://evertpot.com/filesystem-encoding-and-php/告诉我们,非拉丁字符在PHP Windows中很麻烦.似乎只能看到和打开由Windows 1252字符集字符组成的文件.

您面临的挑战是将文件名转换为与Windows 1252兼容.正如您在问题中所指出的,最好不要重命名已经兼容的文件.我将您的尝试重做为:

import os
from glob import glob
import shutil
import urllib

files = glob(u'*.txt')
for my_file in files:
    try:
        print "File %s" % my_file
    except UnicodeEncodeError:
        print "File (escaped): %s" % my_file.encode("unicode_escape")
    new_name = my_file
    try:
        my_file.encode("cp1252" , "strict")
        print "    Name unchanged. Copying anyway"
    except UnicodeEncodeError:
        print "    Can not convert to cp1252"
        utf_8_name = my_file.encode("UTF-8")
        new_name = urllib.quote(utf_8_name )
        print "    New name: (%% encoded): %s" % new_name

    shutil.copy2(my_file, os.path.join("fixed", new_name))

分解:

>打印文件名.默认情况下,Windows Shell仅在本地DOS代码页中显示结果.例如,我的s​​hell可以显示ü.txt,但€.txt显示为?.txt.因此,您需要注意Python抛出异常,因为它无法正确打印.此代码尝试打印Unicode版本,但改为打印Unicode代码点转义符.
>尝试将字符串编码为Windows-1252.如果可行,则文件名正常
>其他:将文件名转换为UTF-8,然后对其进行百分比编码.这样,文件名保持唯一,您可以在PHP中逆转此过程.
>将文件复制到新文件/已验证文件.

例如,你好.txt变成你好.txt

上一篇:Linux系统编程【3.2】——ls命令优化版和ls -l实现


下一篇:Tesseract-OCR 4.1.0 安装及使用—windows及CentOS【附Java源码实现】