在Windows上的Python 3.4中处理Unicode文件名

时间:2015-11-22 18:30:37

标签: python windows python-3.x unicode

我正在尝试找到一种可靠的方法在Python上扫描Windows上的文件,同时允许文件名中可能存在各种Unicode代码点。我已经看到了几个针对这个问题提出的解决方案,但它们都不适用于我在扫描真实软件和用户创建的文件名时遇到的实际问题所有

下面的代码示例试图解开并演示核心问题。它在子文件夹中创建了三个文件,其中包含我遇到的各种变体,然后尝试扫描该文件夹并显示每个文件名,后跟文件的内容。尝试读取第三个测试文件时会崩溃,OSError [Errno 22]参数无效。

import os

# create files in .\temp that demonstrate various issues encountered in the wild
tempfolder = os.getcwd() + '\\temp'
if not os.path.exists(tempfolder):
    os.makedirs(tempfolder)
print('file contents', file=open('temp/simple.txt','w'))
print('file contents', file=open('temp/with a ® symbol.txt','w'))
print('file contents', file=open('temp/with these chars ΣΑΠΦΩ.txt','w'))

# goal is to scan the files in a manner that allows for printing
# the filename as well as opening/reading the file ...
for root,dirs,files in os.walk(tempfolder.encode('UTF-8')):
    for filename in files:
        fullname = os.path.join(tempfolder.encode('UTF-8'), filename)
        print(fullname)
        print(open(fullname,'r').read())

正如代码中所说,我只是希望能够显示文件名并打开/读取文件。关于文件名的显示,我不关心Unicode字符是否针对特殊情况正确呈现。我只想以唯一标识正在处理哪个文件的方式打印文件名,并且不会为这些不寻常的文件名引发错误。

如果您注释掉最后一行代码,此处显示的方法将显示所有三个文件名,没有错误。但它不会在名称中打开带有其他Unicode的文件。

是否有一种方法可以在Python中可靠地显示/打开所有这三种文件名变体?我希望有这种方法,而我对Unicode细微之处的有限把握使我无法看到它

1 个答案:

答案 0 :(得分:3)

以下工作正常,如果将文件保存在声明的编码中, if if 使用支持显示字符的IDE或终端编码。请注意,这不必是UTF-8。文件顶部的声明仅是源文件的编码。

#coding:utf8
import os

# create files in .\temp that demonstrate various issues encountered in the wild
tempfolder = os.path.join(os.getcwd(),'temp')
if not os.path.exists(tempfolder):
    os.makedirs(tempfolder)
print('file contents', file=open('temp/simple.txt','w'))
print('file contents', file=open('temp/with a ® symbol.txt','w'))
print('file contents', file=open('temp/with these chars ΣΑΠΦΩ.txt','w'))

# goal is to scan the files in a manner that allows for printing
# the filename as well as opening/reading the file ...
for root,dirs,files in os.walk(tempfolder):
    for filename in files:
        fullname = os.path.join(tempfolder, filename)
        print(fullname)
        print(open(fullname,'r').read())

输出:

c:\\temp\simple.txt
file contents

c:\temp\with a ® symbol.txt
file contents

c:\temp\with these chars ΣΑΠΦΩ.txt
file contents

如果您使用的终端不支持对文件名中使用的字符进行编码,您将获得UnicodeEncodeError。变化:

print(fullname)

为:

print(ascii(fullname))

您将看到文件名已正确读取,但无法在终端编码中打印一个或多个符号:

'C:\\temp\\simple.txt'
file contents

'C:\\temp\\with a \xae symbol.txt'
file contents

'C:\\temp\\with these chars \u03a3\u0391\u03a0\u03a6\u03a9.txt'
file contents