在Windows中写入Unicode内容和Unicode文件名

2 投票
2 回答
4024 浏览
提问于 2025-04-16 19:08
#source file is encoded in utf8
import urllib2
import re

req = urllib2.urlopen('http://people.w3.org/rishida/scripts/samples/hungarian.html')
c = req.read()#.decode('utf-8')

p = r'title="This is Latin script \(Hungarian language\)">(.+)'
text = re.search(p, c).group(1)

name = text[:10]+'.txt'  #file name will have special chars in it

f = open(name, 'wb')
f.write(text)  #content of file will have special chars in it
f.close()   


x = raw_input('done')

你可以看到这个脚本做了几件事情: - 从一个网页读取已知包含unicode字符的内容,并存储到一个变量中。

(源文件是以utf-8格式保存的,但这应该没什么关系,除非在源代码中实际定义了unicode字符串……正如你所看到的,unicode字符串是动态定义到一个变量中的。在这种情况下,源文件的编码不应该影响结果。)

  • 创建一个包含unicode字符的文件名。
  • 将unicode内容写入这个文件。

下面是我遇到的奇怪情况(Windows 7,Python 2.7): 当我不使用decode函数时:

c = req.read()

文件的名字会变得很奇怪,但文件的内容是可以读的(也就是说,你可以看到正确的匈牙利unicode字符)。

然而,当我使用decode函数时:

c = req.read().decode('utf-8')

打开文件时不会出错(确实是用'w'模式创建的),而且生成的文件名是可以读的,现在显示的是正确的unicode字符。

到目前为止一切都很好,对吧? 可是,当我尝试将unicode内容写入文件时,就会出错:

    f.write(text)  #content of file will have special chars in it
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 8: ordinal not in range(128)

你看,我似乎无法两全其美…… 要么我能正确写出文件名,要么我能正确写出文件内容……

我该如何做到两者兼得呢?

我也尝试过用

f = codecs.open(name, encoding='utf-8', mode='wb')

但也出错了……

2 个回答

4

虽然winterTTR的回答是有效的,但我发现这个方法有点复杂。其实,你只需要对写入文件的数据进行编码就可以了。文件名不需要编码,文件名和内容都会变得“可读”。

content = '\xunicode chars'.decode('utf-8')
f = open(content[:5]+'.txt', 'wb')
f.write(content.encode('utf-8'))
f.close()
4

你遇到的唯一问题似乎就是你原始文件的文件名“看起来很乱”。这个可以解决你的问题:

f = open(name.decode('utf-8').encode( sys.getfilesystemencoding() ) , 'wb')

撰写回答