如何在Python中从文件中读取字节

8
类似于这个问题,我正在尝试读取ID3v2标签头,并且在尝试获取Python中的单个字节时遇到了困难。
我首先将所有十个字节读入字符串中。然后我想解析出各个信息片段。
我可以从字符串中获取两个版本号字符,但是我不知道如何将这两个字符转换为整数。
struct包似乎是我想要的,但我无法让它工作。
以下是我的代码(顺便说一句,我是Python的新手...所以请对我温柔点):
def __init__(self, ten_byte_string):
        self.whole_string = ten_byte_string
        self.file_identifier = self.whole_string[:3]
        self.major_version = struct.pack('x', self.whole_string[3:4]) #this 
        self.minor_version = struct.pack('x', self.whole_string[4:5]) # and this
        self.flags = self.whole_string[5:6]
        self.len = self.whole_string[6:10]

打印除了undefined和null以外的任何值都是没有意义的,因为它们没有被正确格式化。

4个回答

16

如果你有一个包含2个字节的字符串,并希望将其解释为16位整数,可以通过以下方式实现:

>>> s = '\0\x02'
>>> struct.unpack('>H', s)
(2,)

请注意,> 表示大端序(整数的最高位排在最前面)。这是 id3 标签使用的格式。

对于其他大小的整数,您需要使用不同的格式代码。例如,“i”表示带符号的 32 位整数。有关详细信息,请参阅 help(struct)。

您还可以一次解包多个元素。例如,要解包 2 个无符号短整型,后跟一个带符号的 32 位值:

>>> a,b,c = struct.unpack('>HHi', some_string)

根据你的代码,你要按顺序查找:

  • 一个3个字符的字符串
  • 2个单字节值(主版本和次版本)
  • 一个1字节标记变量
  • 一个32位长度数量

此格式字符串应为:

ident, major, minor, flags, len = struct.unpack('>3sBBBI', ten_byte_string)

4

为什么要自己写?(假设您尚未查看这些其他选项。)有一些Python中用于读取MP3中ID3标签信息的选项。请查看我在此问题下的答案。


1
我确实看到了它们。但这实际上是为学校的一个项目,我们决定编写自己的解析器。 - jjnguy

2

我正在尝试读取一个ID3v2标签头

顺便说一下,这方面已经有一个模块了。

这个

2

我本来想推荐使用struct包,但你说你已经尝试过了。试试这个:

self.major_version = struct.unpack('H', self.whole_string[3:5])

pack()函数将Python数据类型转换为位,而unpack()函数将位转换为Python数据类型。


对于“H”,您需要使用2字节切片。 - Brian
你说得对,我忽略了那个问题。我会修复我的示例让它能正常运行,但是你的答案更好。 - Greg Hewgill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接