【问题标题】:Reading and writing binary data of dynamic sizes question读写动态大小的二进制数据问题
【发布时间】:2010-12-13 17:44:39
【问题描述】:

我正在尝试以二进制模式从文件中读取数据并操作该数据。

 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 0A,就会添加 0D。在图像文件中,它可能是一个不同的字节,我不记得了,可能需要测试它。 我编写新文件的代码非常简单,使用内容作为保存所有数据的字符串缓冲区。

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

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

【问题讨论】:

  • 您可以拨打resultfile.read()阅读整个文件。
  • resultfile.read() 将文件的全部内容作为字符串返回。你有什么理由先抓住尺寸吗?
  • 没有理由,我只是不知道 read() 会返回整个文件。
  • 你正在做的应该工作。贴一个完整的读写文件内容的例子,让我们了解问题所在。
  • 进行了编辑以显示我的意思。

标签: python binaryfiles


【解决方案1】:

您需要像打开输入文件一样以二进制模式打开输出文件。否则,换行符可能会改变。您可以看到这就是您的十六进制转储中发生的情况: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)

【讨论】:

  • 谢谢,我把模式改成了“ab”,效果很好。非常感谢大家。
  • @day break:如果您觉得这个答案有帮助,您应该点击旁边的绿色复选标记“接受”它作为正确答案。
【解决方案2】:

你得到的结果“只是字节本身”。您可以将它们 write() 到打开的文件中以复制它们。

“似乎只要有 0D 0A 就会添加 0D”

听起来您在 Windows 上,并且您正在以文本模式而不是二进制模式打开您的文件之一。

【讨论】:

    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    相关资源
    最近更新 更多