我有一个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代码页中显示结果.例如,我的shell可以显示ü.txt,但€.txt显示为?.txt.因此,您需要注意Python抛出异常,因为它无法正确打印.此代码尝试打印Unicode版本,但改为打印Unicode代码点转义符.
>尝试将字符串编码为Windows-1252.如果可行,则文件名正常
>其他:将文件名转换为UTF-8,然后对其进行百分比编码.这样,文件名保持唯一,您可以在PHP中逆转此过程.
>将文件复制到新文件/已验证文件.
例如,你好.txt变成你好.txt