Python struct.unpack - 将二进制字符串文字转换为ascii文本写入文件

时间:2017-05-12 08:22:03

标签: python-3.x lambda struct.pack

我们使用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'),因此将其写为普通字符串值。

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

1 个答案:

答案 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