在Python中读取字节 - io.BytesIO v / s binascii.unhexlify

时间:2018-01-07 05:46:33

标签: python python-3.x

以下两种读取字节的方法有什么区别?

stream = BytesIO(unhexlify('000000010000'))
print(int.from_bytes(stream.read(4), byteorder="big"))  //prints 1


bytes = unhexlify('000000010000')
print(int.from_bytes(bytes[:4], byteorder="big"))  //prints 1

哪个更好?为什么呢?

2 个答案:

答案 0 :(得分:3)

如果你知道你的字符串是hex字符串,为什么不切片后将其直接转换为intbase为“16”?例如:

>>> my_hex = '000000010000'
>>> int(my_hex[:8], base=16)
1

你必须在这里注意我将索引的字符串切换为“8”而不是4,但由于我们知道它是十六进制字符串,因此我们可以相应地对其进行切片,因为2字符代表{{ 1}}数字。

以下是您和我的解决方案的性能比较:

hex

如您所见,只使用mquadri$ python3 -m timeit "my_hex = '000000010000'; int(my_hex[:8], base=16)" 1000000 loops, best of 3: 0.581 usec per loop mquadri$ python3 -m timeit -s "from io import BytesIO; from binascii import unhexlify" "stream = BytesIO(unhexlify('000000010000')); int.from_bytes(stream.read(4), byteorder='big')" 1000000 loops, best of 3: 1.15 usec per loop mquadri$ python3 -m timeit -s "from binascii import unhexlify" "bytes = unhexlify('000000010000'); int.from_bytes(bytes[:4], byteorder='big')" 1000000 loops, best of 3: 0.764 usec per loop 进行转换比您的两种解决方案都更有效。

但是,如果您只对所提到的解决方案感兴趣,那么我会建议不使用int的解决方案,因为:

  • 不使用io.BytesIO,您需要一个较小的ByteIO
  • 相对而言,您的第二个解决方案看起来也更简单

注意:对于效果衡量,我不计算导入的时间,以防有人计划说“这个差异与额外导入“;)

答案 1 :(得分:1)

使用IO构造(StringIOBytesIO)的目的是处理模仿流的对象(如文件)。因此,您的第一个解决方案是将字节包装在类似文件的对象中,并从该包装器中读取,就好像它是一个文件一样。你的第二个解决方案只是从字节读取。

我说如果您的代码的语义不要求字节是流,请跳过IO解决方案直接到源。