我们使用struct.unpack来读取由所有C结构字段及其值(整数和字符串)的转储创建的二进制文件。然后使用解压缩的元组创建字段及其值的中间字典表示,稍后将其写入文本文件输出。
文本文件输出显示如下字符串:
ID = b'000194901137\x00\x00\x00\x00'
timestampGMT = 1489215906
timezoneDiff = -5
timestampPackage = 1489215902
version = 293
type = b'FULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
该程序早先用python 2.6编写,以前它工作正常。在写入文本文件时,我们使用了下面的lambda表达式来删除不需要的十六进制字符:
filtered_string = filter(lambda x: x in string.printable, line)
移动到Python 3.5,lambda表达式不再受支持,因为它现在返回一个不能轻易转换为字符串的过滤器。
将这些二进制字符串文字转换为等效的ascii文本的Pythonic方法是什么(没有尾随NUL' \ x00'),因此将其写为普通字符串值。
此外,由于每个文件需要处理数千个条目(同样还有多个文件),因此在当前上下文中寻找一些最佳解决方案。
答案 0 :(得分:0)
在Python 2中,你可以互换地使用str类型的文本和二进制数据,它工作正常。从Python3二进制数据读取是
类型为bytes
,并且它不像Python 2中那样共享公共基类。
$ python3
Python 3.5.0 (default, Sep 15 2015, 13:42:03)
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> type(b'aaa')
<class 'bytes'>
>>> type(b'aaa').__mro__
(<class 'bytes'>, <class 'object'>)
>>> type('aaa')
<class 'str'>
>>> type('aaa').__mro__
(<class 'str'>, <class 'object'>)
$ python
Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> type(b'aaa').__mro__
(<type 'str'>, <type 'basestring'>, <type 'object'>)
>>> type('aaa').__mro__
(<type 'str'>, <type 'basestring'>, <type 'object'>)
二进制文件中编码的字符串作为bytes
类型的字符串文字读入,需要将其转换为str
(Unicode)类型,以便作为普通字符串显示/写入文件。
从struct.unpack()
检索元组后,我执行以下操作:
valTuple = struct.unpack(fmt, self.data[off : goff + struct_size])
valList = list(valTuple)
for i in range(len(valList)):
if type(valList[i]) == bytes:
valList[i] = valList[i].rstrip(b'\x00').decode()
阅读此https://docs.python.org/3/howto/pyporting.html#text-versus-binary-data