以下内容代表从文件中提取的二进制图像(在字节之间插入空格以使读取更加容易)。文件以“ rb”模式打开。
01 77 33 9F 41 42 43 44 00 11 11 11
在Python 2.7中,我将其读取为字符串,并使用ord()提取二进制值,然后可以提取甚至搜索字符串中的特定文本值(例如字符4中的“ ABCD” -7)。二进制字节可以是0-FF之间的任何值。我一直在推迟到python 3的转换。
在Python 3中,我需要能够将字节字符串视为二进制和ascii(而非unicode)值的混合。格式不是固定的,它由数据结构组成。例如,字节2中的33可能是一条记录长度,它告诉我下一条记录的开始位置。换句话说,我不能只说我知道文本字符串始终在位置4。
我不写文件,只是使用它,所以更改它不是一个选择。
我已经看到了很多使用b'和其他东西转换固定字符串的示例,但是我需要一种混合这些值的方法,将2字节到8字节的字节提取为16位到64位单词,然后提取/搜索较大字符串中的ASCII字符串。
Python 3中的字节/字符分隔对于我需要的东西似乎有些僵硬。我确定有办法做到这一点,但我还没有找到一个似乎可以解决此问题的示例或已回答的问题。
这是一个简化的示例,我无法提供真实数据(它是专有数据),但这说明了问题所在。实际文件可能很短(<1K)或很大(> 100K),其中包含多个不同大小的记录。
是否存在一种简单,直接的方法来本质上复制Python 2.7中的功能?
这是在Windows上。
谢谢
答案 0 :(得分:0)
在Python 3中,我需要能够将字节字符串视为二进制和ascii(而非unicode)值的混合。格式不是固定的,它由数据结构组成。例如,字节2中的33可能是一条记录长度,它告诉我下一条记录的开始位置。换句话说,我不能只说我知道文本字符串始终在位置4。
在执行操作时,以二进制模式读取文件。这将产生一个bytes
对象,该对象在3.x中与str
(在2.x中将是不一样)
根据需要将字节解释为字节,以弄清楚数据的一般结构。像以前一样切片bytes
会产生另一个bytes
;索引生成的int
带有单个字节的数值(不是像以前一样)-不需要ord
。
确定了代表字符串的字节的子集后(为方便起见,您将其切开),请使用适当的编码转换为字符串 : str(my_bytes, 'ascii')
。请注意,ASCII将不处理字节值0x80到0xFF;尤其是对于二进制格式的旧文件格式,很有可能您的数据实际上是 类似于Latin-1:str(my_bytes, 'iso-8859-1')
。
在字符串中搜索特定的文本值
您可以在文本级别或字节级别进行搜索-bytes
对象支持in
运算符,可以搜索bytes
的子序列或单个整数值。在字符串转换之前还是之后进行搜索更有意义,这取决于您在做什么。
使用b'和其他方法转换固定字符串
b''
只是 literal bytes
对象的语法。如果您要求从文件中读取内容的repr
,就会看到此内容。将b
前缀到代码中现有的字符串文字上并不会真正“转换”任何东西,而是将其替换为您应该首先拥有的值。
2字节到8字节的值,从16位到64位字
文档至少说得尽我所能:
>>> help(int.from_bytes)
Help on built-in function from_bytes:
from_bytes(...) method of builtins.type instance
int.from_bytes(bytes, byteorder, *, signed=False) -> int
Return the integer represented by the given array of bytes.
The bytes argument must be a bytes-like object (e.g. bytes or bytearray).
The byteorder argument determines the byte order used to represent the
integer. If byteorder is 'big', the most significant byte is at the
beginning of the byte array. If byteorder is 'little', the most
significant byte is at the end of the byte array. To request the native
byte order of the host system, use `sys.byteorder' as the byte order value.
The signed keyword-only argument indicates whether two's complement is
used to represent the integer.