【问题标题】:Read string from binary file从二进制文件中读取字符串
【发布时间】:2014-06-18 21:34:52
【问题描述】:

我想从文件中读取字节 1,2 和 3。我知道它对应于一个字符串(在这种情况下,它是 Linux 二进制标头的 ELF

以下示例我可以在网上找到我想出的:

with open('hello', 'rb') as f:
    f.seek(1)
    bytes = f.read(3)
    string = struct.unpack('s', bytes)
    print st

查看struct 的官方文档,似乎将s 作为参数传递应该允许我读取字符串。

我得到错误:

st = struct.unpack('s', bytes)
struct.error: unpack requires a string argument of length 1

编辑:使用 Python 2.7

【问题讨论】:

  • 请指定您使用的 Python 版本。在 Python 2 中,“str”和“bytes”是别名。在 Python 3 中,file.read() 尝试使用 UTF-8 编码将字节转换为 unicode。
  • @Grapsus:这是错误的。 f.read() 在 Python 2 和 3 上返回 bytes 如果文件以二进制模式打开 'b'(OP 使用 'rb' 即二进制)。 text 模式下的open 使用locale.getpreferredencoding(False) 编码,有时 在 Python 3 中可能是 utf-8
  • 不要使用bytes 名称。它隐藏了内置函数。

标签: python string python-2.7 binary


【解决方案1】:

在你的特殊情况下,检查就足够了

if bytes == 'ELF':

一步测试所有三个字节为三个字符ELF

但如果你想检查数值,你不需要在这里解压任何东西。只需使用ord(bytes[i]) (with i in 0, 1, 2) 即可得到三个字节的字节值。

你也可以使用

byte_values = struct.unpack('bbb', bytes)

获取三个字节的元组。如果字节具有这样的可命名语义,您还可以即时解压缩该元组:

width, height, depth = struct.unpack('bbb', bytes)

使用'BBB' 而不是'bbb',以防您的字节值是无符号的。

【讨论】:

  • 实际上,您的bytes 已经是您要查找的字符串,即。 e.你可以测试if bytes == 'ELF': …。有时事情很简单;-)
  • 为什么是评论:f.read(3) == b'ELF' 应该在答案的顶部。
  • 如果你需要整数而不是字节串;你可以使用bytearray(bytestring)a = array.array('B'); a.fromfile(file, 3)。要从二进制文件中读取结构化数据,您可以使用struct.Struct.unpack_from(buf) or file.readinto(ctypes_structure) or (ctypes_structure * N).from_buffer(mmap_file)
  • 在撰写我的评论时,评论中只有一个附加问题指出常量'ELF'
【解决方案2】:

在 Python 2 中,read 返回一个字符串;在“字节串”的意义上。要获取单个字节,请使用bytes[i],它将返回另一个字符串,但只有一个字节。如果需要字节的数值,请使用ordord(bytes[i])。最后,要获取所有字节的数值,请使用map(ord, bytes)

In [4]: s = "foo"

In [5]: s[0]
Out[5]: 'f'

In [6]: ord(s[0])
Out[6]: 102

In [7]: map(ord, s)
Out[7]: [102, 111, 111]

【讨论】:

  • 我对python2.7中读取的返回类型有点困惑。我以二进制模式打开了一个文件,然后读取了一个字节,比如byte = f.read(1)。当我执行print type(byte) 时,它会显示str。 “字节串”与普通字符串不同。 python中的哪种数据类型映射到“字节串”
猜你喜欢
  • 2012-09-05
  • 2020-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多