当我使用简单的 I/o 调用来读取系统上的特定文件时,例如:
f = open('file.ini')
for line in f.readlines():
print line
我得到这样的输出:
H E L L O ! W H Y A R E T H E R E S O M A N Y S P A C E S ?
我认为它是 Unicode,但我不太清楚如何将其读取为 Unicode/将其转换为 ascii。建议?
当我使用简单的 I/o 调用来读取系统上的特定文件时,例如:
f = open('file.ini')
for line in f.readlines():
print line
我得到这样的输出:
H E L L O ! W H Y A R E T H E R E S O M A N Y S P A C E S ?
我认为它是 Unicode,但我不太清楚如何将其读取为 Unicode/将其转换为 ascii。建议?
codecs
尝试使用以使事情更容易打开文件。
例子:
import codecs
f = codecs.open('file.ini', encoding='utf-16-le') # You can experiment with different encodings
for line in f: # note, the readlines is not really needed
print line, # the comma strips the trailing newline in case that's bothering you
PS:如果你不知道编码,我建议看这个问题:Determine the encoding of text in Python
非常规则的空格通常表明您的数据是用 UTF16 编码的——通常您看到的是每隔一个字节是一个 0 字节。您可以通过打印出您正在阅读的实际二进制数据来确认这一点:
f = open('file.ini')
line in f.readline():
print map(ord, line)
如果你看到这样的输出:
[..., 68, 0, 65, 0, 76, 0, 76, 0, 79, ...]
那么几乎可以肯定是这样。
那么,诀窍是确定是偶数字节是 0,还是奇数字节。有两种 UTF-16 编码:Big-endian 和 little-endian,以先出现的字节的重要性命名。如果你的 0 出现在它们关联的字符之前,那么文件是大端的,你可以像这样打开它(Python 3.x):
f = open('file.ini', encoding='utf16be')
在 Python 2.x 中,导入codecs
模块来执行此操作:
import codecs
f = codecs.open('file.ini', encoding='utf16be')
如果后面是 0,则替换为“utf16le”。
(您需要确保在读取文件时对其进行解码,或者在解码之前将整个内容读入内存。您绝对不想在解码之前将行分开)
如果幸运的话,文件的开头写了一个字节顺序标记,这个字符是 U+FEFF——如果前两个字节是[254, 255]
,那么编码是 big-endian,如果[255, 254]
是 ,那么它是 little-字节序。
如果这些都不适用,那么您可能没有查看 UTF-16 数据,您将不得不做更多的研究以确定您正在查看的编码。