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

时间:2015-07-09 16:00:22

标签: python python-2.7 binary

我正在读这个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..对二进制文件的处理应该是正确的。

为什么二进制比较错了?

1 个答案:

答案 0 :(得分:3)

首先,Python 2 不使用bytes() 。名称bytesstr()的别名。 fp.read()返回表示字节的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基类,至少不会捕获内存错误,键盘中断和生成器退出异常。你真的应该缩小范围,直到你希望你的代码处理的实际例外(例如,不是所有)。