为什么这个二进制比较在 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()
。名称 bytes
是 str()
的别名。 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)。
我正在阅读这篇文章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()
。名称 bytes
是 str()
的别名。 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)。