通过Python 3修改非文本文件

时间:2015-10-12 07:02:47

标签: python image python-3.x utf-8 utf8-decode

我正在研究加密/解密程序,我让它处理文本文件;但是,我无法打开任何其他格式。例如,如果我这样做:

a_file = open('C:\Images\image.png', 'r', encoding='utf-8')
for a_line in a_file:
    print(a_line)

我明白了:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\WinPython-64bit-3.4.3.4\python-3.4.3.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 685, in runfile
execfile(filename, namespace)
File "C:\WinPython-64bit-3.4.3.4\python-3.4.3.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
File "C:/Comp_Sci/Coding/line_read_test.py", line 2, in <module>
for a_line in a_file:
File "C:\WinPython-64bit-3.4.3.4\python-3.4.3.amd64\lib\codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte

我做错了什么?

2 个答案:

答案 0 :(得分:4)

简短版本:您正在以文本模式打开二进制文件。使用'rb'代替'r'(并删除encoding参数),您将做得很好。

长版本:Python 3对 bytestrings Unicode字符串进行了非常严格的区分。 str类型仅包含 Unicode字符串; str的每个字符都是一个Unicode代码点。另一方面,bytes类型表示一系列不一定与文本对应的8位值。例如,.PNG文件应作为bytes对象加载,而不是作为str对象加载。通过将encoding="utf-8"参数传递给open(),您告诉Python您的文件只包含有效的UTF-8文本,而.PNG显然没有。相反,您应该将文件打开为具有'rb'的二进制文件,而不是使用任何编码。然后,当您阅读文件时,您将获得bytes个对象而不是str个对象,并且您需要以不同方式对待它们。

我看到@ ignacio-vazquez-abrams在我输入这个答案时已经发布了很好的示例代码,所以我不会重复他的努力。他的代码是正确的:使用它,你会没事的。

答案 1 :(得分:3)

您将其作为文本文件打开,并假设您可以读取行并从中有意义地打印任何内容。

with open(r'C:\Images\image.png', 'rb') as a_file:
  while True:
    data = a_file.read(32)
    if not data:
      break
    print(data)