2016-04-16 70 views
1

我目前正在试验Python 3如何在读取和写入数据时处理字节,并且遇到了一个特别令人不安的问题,我似乎无法找到其来源。我是从一个JPEG文件中低频读取字节,使用ord()将它们转换为整数,然后使用行chr(character).encode('utf-8')将这些字节返回到它们的原始字符,并将它写回JPEG文件。没问题吗?那么当我尝试打开JPEG文件时,我得到一个Windows 8.1通知,说它无法打开照片。当我检查两个文件相互之间是5.04MB,另一个是7.63MB,这让我非常困惑。向文件写入更多数据而不是读取数据?

def __main__(): 
    operating_file = open('photo.jpg', 'rb') 

    while True: 
     data_chunk = operating_file.read(64*1024) 
     if len(data_chunk) == 0: 
      print('COMPLETE') 
      break 
     else: 
      new_operation = open('newFile.txt', 'ab') 
      for character in list(data_chunk): 
       new_operation.write(chr(character).encode('utf-8')) 


if __name__ == '__main__': 
    __main__() 

这是我正在使用的确切代码,关于正在发生的事情以及如何修复它的任何想法?

注意:我假设list(data_chunk)提供的数字列表相当于ord()

+1

你为什么使用'list'?就我所见,'data_chunk'将是一个字节对象,可以一次对字节进行迭代。我也困惑你为什么指定'uff-8'。如果你正在读取字节,那么你不希望它们转换为字符。 – cdarke

+0

在小得多的测试文件上尝试您的代码 - 它不一定是真正的JPEG - 具有较小的“块大小”,然后比较两个文件的大小和内容。您也可以轻松测试您的假设是否正确。顺便说一句,在Python 3中打开一个以二进制模式读取文件的正确方法是'open(filename,'r',newline ='')'。写作是相似的。 – martineau

+2

将字节编码为用于写入JPEG文件的UTF-8是错误的。它将采用任何高于0x7F的字节并将其编码为多个字节,从而破坏数据。 –

回答

2

下面是一个简单的例子,你可能想一起玩:

import sys 

f = open('gash.txt', 'rb') 
stuff=f.read() # stuff refers to a bytes object 
f.close() 

print(stuff) 

f2 = open('gash2.txt', 'wb') 

for i in stuff: 
    f2.write(i.to_bytes(1, sys.byteorder)) 

f2.close() 

正如你所看到的,bytes对象是可迭代的,但在for循环中,我们取回iint。为了将其转换为一个字节,我使用了int.to_bytes()方法。

+0

OP使用的是Python 3,所以打开二进制模式文件的方式不正确(即使它可能在某些操作系统上可用)。 – martineau

+0

@martineau:这段代码在python 3.5上正常工作。它有什么问题? – cdarke

+1

谢谢,我能够用它来解决我的问题。 – TheMountainFurnaceGabriel

0

当你有一个代码点并且你用UTF-8对它进行编码时,结果可能包含比原始字节更多的字节。

有关具体示例,请参阅WikiPedia page并考虑十六进制值0xA2

这是一个单一的二进制值,小于255,但是当编码为UTF8时,它变为0xC2, 0xA2

鉴于您将字节从您的源文件中提取出来,我的第一个建议是将字节直接传递给目标文件的编写者。

如果您试图了解文件I/O的工作方式,请在使用二进制文件模式时小心encode()。二进制文件不需要编码或解码 - 它们是原始数据。

相关问题