如何打开一个 zip 文件中的 Unicode 文本文件?
如何打开一个 zip 文件中的 Unicode 文本文件?
我尝试了以下代码:
with zipfile.ZipFile("5.csv.zip", "r") as zfile: for name in zfile.namelist(): with zfile.open(name, 'rU') as readFile: line = readFile.readline() print(line) split = line.split('\t')
它的答案是:
b'$0.0\t1822\t1\t1\t1\n' Traceback (most recent call last) File "zip.py", line 6 split = line.split('\t') TypeError: Type str doesn't support the buffer API
如何以Unicode方式打开文本文件而不是以`b`的方式?
在上述代码中,问题的出现是由于尝试打开一个包含Unicode文本文件的zip文件时遇到了编码问题。为了解决这个问题,可以使用io.TextIOWrapper()将字节流转换为Unicode流。同时需要注意的是,TextIOWrapper()默认使用通用换行模式。以下是解决方法的代码示例:
encoding = 'utf-8' with zipfile.ZipFile("5.csv.zip") as zfile: for name in zfile.namelist(): with zfile.open(name) as readfile: for line in io.TextIOWrapper(readfile, encoding): print(repr(line))
需要注意的是,自Python 3.4版本起,rU
模式在zfile.open()
中已被弃用。这种方法可以避免在处理多字节编码时出现的问题。同时,对于无法在打开文件时提供编码或使用codecs.open方法的情况,TextIOWrapper()方法是最安全的选择。
这种方法适用于Python 3中的处理,并且在处理sys.stdin、sys.stdout和subprocess模块中的文本管道时也是常用的方法。对于Python 2,可以考虑使用codecs.getreader(encoding)(file_obj)方法。在处理zip文件时,TextIOWrapper()方法是最好的选择。
如何在zip文件中打开一个Unicode文本文件?
问题原因:在Python 2.x版本中,如果要打开一个Unicode文本文件,需要使用正确的解码方式来处理文件内容,否则会出现编码错误。这个问题的解决方法是使用io.TextIOWrapper来打开文件,并指定正确的编码方式进行解码。
解决方法:
1. 如果文件是utf-8编码,可以使用以下代码来打开文件:
with zfile.open(name, 'rU') as readFile: line = readFile.readline().decode('utf8') # 其他操作
2. 如果要遍历文件内容,可以使用codecs.iterdecode来处理文件内容,但无法使用readline()方法。
with zfile.open(name, 'rU') as readFile: for line in codecs.iterdecode(readFile, 'utf8'): print line # 其他操作
需要注意的是,这两种方法对于多字节编码不一定安全。例如,小端UTF-16编码将换行符表示为字节b'\x0A\x00'。一个不支持Unicode的工具在寻找换行符时会将其错误地分割,导致空字节留在下一行。在这种情况下,需要使用不尝试通过换行符分割输入的方法,如ZipFile.read,并一次性解码整个字节字符串。这对于utf-8编码不是一个问题。
我已经验证过了,确实使用.readline().decode('utf-16')会出现异常。更糟糕的是,codecs.iterdecode()会默默地产生错误的输出(换行符会移动到下一行)。io.TextIOWrapper()可以避免这些问题。
我被告知Python 3已经解决了Unicode错误。我错过了什么吗?
- 嗯,我不知道你错过了什么,因为你没有给出任何上下文。Python 3使得在意外混合编码字节和Unicode对象方面更加困难,这是Python 2中常见的令人困惑的错误的常见原因,因为它在表面上是有效的,直到你遇到实际导致默认字符编码隐式解码/编码的数据。但这并不是魔法,你仍然需要解码将二进制数据转换为字符或编码进行反向操作。
问题的原因是由于尝试将字节与Unicode混合使用。split函数的参数也必须是字节字符串。为了获得Unicode字符串,可以使用decode函数。
解决方法是将字节字符串转换为Unicode字符串。可以使用decode函数,并指定字符编码为utf-8。以下是解决方法的示例代码:
line = b'$0.0\t1822\t1\t1\t1\n' line.split(b'\t') line.decode('utf-8')
以上代码中,将字节字符串line通过split函数按制表符\t进行拆分,返回一个包含拆分结果的列表。然后,通过decode函数将字节字符串line转换为Unicode字符串,并指定字符编码为utf-8。转换后的结果将被输出。