0

我们使用 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 文本(没有尾随 NUL'\x00')的 Pythonic 方法是什么,因此将其写为普通字符串值。

此外,由于每个文件要处理数千个条目(同样有多个文件),因此在当前上下文中寻找一些可能的最佳解决方案。

4

1 回答 1

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

于 2017-05-18T09:11:30.727 回答