为什么这个二进制比较在 Python 中是错误的?

Why this binary comparison wrong in Python?

我正在阅读这篇文章thread,但我无法进行二进制比较

代码

#!/usr/bin/python
import sys
import os

fp = open("/home/masi/r.raw", "rb")

# I think you cannot do binary comparison with seek so read
try:
    aBuf = bytes(fp.read(4))
    while aBuf[:3] != b'\x58\x5E':
        aBuf = bytes(fp.read(4))

except:
    print "File end at position : ", fp.tell()

finally:
    fp.close()

在 Debian 中获取输出 Linux 8.1

File end at position :  4

数据 r.raw 是二进制,其中第一行十六进制:

48000000fe5a1eda480000000d00030001000000cd010000010000000000

所以 while 循环应该至少到位置 60。 b'\x..\x.. 对二进制的处理应该是正确的。

为什么二进制比较错误?

首先,Python2不使用bytes()。名称 bytesstr() 的别名。 fp.read() returns str 表示字节的对象,字符串文字的 b 前缀是空操作,它只是为了与 Python 向前兼容3.

接下来,您要将 3 个字符的切片与 2 字节的字符串进行比较:

>>> len('\x58\x5E')
2
>>> len('12345'[:3])
3

所以比较永远不会是假的

如果您想测试前 2 个字节,请改用 2 个字符的切片:

while aBuf[:2] != '\x58\x5E':

或使用str.startswith()方法:

while not aBuf.startswith('\x58\x5E'):

当然,这并不能解释您的问题,因为您希望因此读取 整个 文件。

但是,您可能得到的是 IOError,但您使用的是 Pokemon 异常处理;你抓住了他们。不要使用笼统的 except: 语句,您正在捕获所有可能的错误,包括内存错误。

至少 记录您的异常情况:

try:
    aBuf = fp.read(4)
    while aBuf and not aBuf.startswith('\x58\x5E'):
        aBuf = fp.read(4)
except Exception:
    print "File end at position : ", fp.tell()
    import traceback
    traceback.print_exc()

我已将捕获的异常限制在 Exception 基类中,至少不捕获内存错误、键盘中断和生成器退出异常。您真的应该进一步缩小到您希望代码处理的实际异常(例如,不是 everything)。