UnicodeDecodeError:“ utf-8”编解码器无法解码位置0的字节0xa5:无效的起始字节

时间:2019-10-09 12:04:15

标签: python-3.x unicode utf-8 cygwin

$ python3 parse_peak_user_log.py license_usage.bin  --export ~/usage.xlsx --export-type xlsx
Traceback (most recent call last):
  File "parse_peak_user_log.py", line 455, in <module>
    parser.parse()
  File "parse_peak_user_log.py", line 237, in parse
    return self.parse_open_file(open_file)
  File "parse_peak_user_log.py", line 254, in parse_open_file
    if not self.parse_four_cc(open_file):
  File "parse_peak_user_log.py", line 334, in parse_four_cc
    four_cc = self.read_str(open_file, 4, True)
  File "parse_peak_user_log.py", line 354, in read_str
    return str_value.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa5 in position 0: invalid start byte

当我从其他来源收到该代码后,它应该可以工作了,并且确实工作了几天。突然没有修改任何内容,我就陷在这个错误中。我试图在cygwin64或Ubuntu的帮助下运行python脚本,并且在两个终端上我都收到相同的错误。

我对python不太熟悉,但我确实知道问题可能在哪里。我唯一不了解的是脚本中包含以下代码:

def read_str(self, open_file, length, append):
    str_value = open_file.read(length)
    if append:
        self.log_data += str_value
    return str_value.decode('utf-8')

那不是解码问题吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

  

那不是解码问题吗?

仅当您的文件实际以utf-8编码时,情况似乎并非如此。如果文件中的编码为“ latin1”,则“ \ xa5”字节表示“¥”,该编码在世界范围内广泛使用,包括Windows的西方系统中的安装。

如果在此数据中对您来说“¥”的存在对您来说是有意义的,则可以确定文件已使用latin1编码(类似于“ cp1252”,但字符有所不同)-只需将解码行替换为:< / p>

return str_value.decode('latin1')

,您的代码应适用于该文件。否则,即字符应该是另一回事,那么您将不得不通过其他方式猜测文件的正确编码(例如,如果文件位于Cyrillic CP855中,则文件中相同的“ \ xa5”字节代表“ Ц”)。

在上面代码的另一个注释中,该代码尝试以二进制模式读取文件(假定,因为竞赛已被解码),但是,对于字符的所有字节都没有读。也就是说,以utf-8编码的一个字符可以具有1-4个字节的长度-如果“ str_value”读取了部分字符,则解码步骤将失败。 (即使文件实际上是utf-8编码,这里甚至可能是这种情况)。正确的做法是简单地将文件作为文本打开,然后让Python编解码器机制处理解码步骤。

换句话说:任何创建open_file的代码都应执行open("<filename>", "rt", encoding="latin1")((如果其他任何代码将self.log_data视为字节而不是文本,即尝试调用self.log_data.decode ,也应进行更改(只需删除“ .decode”调用即可)