2010-12-13 47 views
0

我想从二进制模式的文件读取数据并操作该数据。读取和写入动态大小的二进制数据问题

try: 
    resultfile = open("binfile", "rb") 
except: 
    print "Error" 
resultsize = os.path.getsize("binfile") 

有一个32字节的头,我解析好,然后二进制数据的缓冲区开始。数据可以是从16到4092的任何大小,并且可以是从文本到PDF或图像或其他任何格式的任何格式。头部有数据的大小,所以得到这个信息我做

contents = resultfile.read(resultsize) 

并且这将整个文件放入一个字符串缓冲区。我发现这可能是我的问题,因为当我尝试将“内容”中的十六进制数据块复制到新文件中时,某些字节无法正确复制,因此PDF和图像将会损坏。

在解释器中打印出一些文件字符串缓冲区,例如“%PDF-1.5 \ r \ n%\ xb5 \ xb5 \ xb5 \ xb5 \ r \ n1 0 obj \ r \ n”当我只是想自己的字节,以便将它们写入一个新的文件。有没有一个简单的解决方案来解决这个我缺少的问题?

这里是我的Python编写的PDF格式和PDF真正的十六进制转储的例子:

25 50 44 46 2D 31 2E 35 0D 0D 0A 25 B5 B5 B5 B5 0D 0D 0A 31 20 30 20 6F 62 6A 0D 0D 0A 

25 50 44 46 2D 31 2E 35 0D 0A 25 B5 B5 B5 B5 0D 0A 31 20 30 20 6F 62 6A 

好像被添加0D每当有0D 0A。在图像文件中,它可能是一个不同的字节,我不记得也可能需要测试它。 我的代码写入新文件非常简单,使用内容作为保存所有数据的字符串缓冲区。

 fbuf = contents[offset+8:size+offset] 
     fl = open(fname, 'a') 
     fl.write(fbuf) 

这是在基于标题中找到的签名的循环中调用的。偏移+8是实际pdf数据的开始,大小是要复制的块的大小。

+2

你可以叫'resultfile.read()'读取整个文件。 – 2010-12-13 17:48:04

+0

'resultfile.read()'将以字符串的形式返回文件的全部内容。你有没有理由首先抓住尺码? – nmichaels 2010-12-13 17:49:53

+0

没理由,我只是不知道read()会返回整个文件。 – 2010-12-13 17:53:49

回答

2

您需要以二进制模式打开您的输出文件,就像您输入文件一样。否则,换行符可能会改变。你可以看到,这是你的十六进制转储会发生什么:0A字符('\n')改变为OD 0A'\r\n')。

这应该工作:

input_file = open('f1', 'rb') 
contents = input_file.read() 

#.... 
data = contents[offset+8:size+offset] #for example 

output_file = open('f2', 'wb') 
output_file.write(data) 
+0

谢谢你,我改变了模式为“ab”,它工作正常。非常感谢大家。 – 2010-12-13 18:36:57

+0

@day破解:如果你发现这个答案有帮助,你应该“接受”,方法是:单击旁边的绿色对勾正确的答案。 – 2010-12-13 19:04:31

0

你得到的结果“只是字节本身”。你可以写()他们到一个打开的文件来复制它们。

“仿佛被添加了0D每当有0D 0A”

听起来你使用的是Windows,并且您打开您的文件中的一个文本模式,而不是二进制。