【问题标题】:Python - Turn a file content into a binary arrayPython - 将文件内容转换为二进制数组
【发布时间】:2017-03-10 09:05:03
【问题描述】:

文件内容:

40 13 123
89 123 2223
4  12  0

我需要将整个 .txt 文件存储为二进制数组,以便稍后将其发送到需要二进制输入的服务器端。


我查看了 Python 的 bytearray 文档。 我引用:

返回一个新的字节数组。 bytearray 类型是 0


我的数字大于 256,对于大于 256 的数字,我需要一个 bytearray 数据结构。

【问题讨论】:

  • 您的意思是要将文本表示形式存储为 int32 数组吗?
  • @xtofl 是的。但我的问题是,在我对每个数字这样做之后,我想把它放在一个二进制对象中吗?如果我访问第一行,我会得到二进制表示的第一个数字。
  • 你有一个你想要的例子吗? "101010" 不是二进制对象,它是表示二进制 42 的字符串。 42,作为一个整数,已经存储为 Python 的二进制文件。
  • @EricDuminil 是的,先生,抱歉我的错误解释。一个字节为 8 位,可以作为binary 数据发送。我需要有许多二进制数字的序列,以便我知道何时停止阅读以了解我的第一个数字,第二个数字等等。一种方法是 xtofl 所说的以 32 位表示。但我不能让 bytearray 存储超过 8 位,因为任何大于 256 的数字都无法存储。
  • 所以只需使用一个 int 数组就可以了。服务器没有明确指定它期望的格式吗?

标签: python python-2.7


【解决方案1】:

您可以使用array/memoryview 方法

import array
a = array.array('h', [10, 20, 300]) #assume that the input are short signed integers
memv = memoryview(a)
m = memv.cast('b') #cast to bytes
m.tolist()

然后给出[10, 0, 20, 0, 44, 1]

根据使用情况,也可以这样做:

L = array.array('h', [10, 20, 300]).tostring()
list(map(ord, list(L)))

这也给了[10, 0, 20, 0, 44, 1]

【讨论】:

  • 不错!我看到还有array.from_list(...)
  • TypeError: cannot make memory view because object does not have the buffer interface 我读到 array.array 对象只在 python 3 上支持这个? stackoverflow.com/questions/4877866/…
  • @xtofl 它在 Python 3 上运行良好,但不幸的是,Python 2.7 不支持在数组上应用 memoryview - bugs.python.org/issue17145
  • @TonyTannous 那么我只需将'h' 更改为'd',即用整数替换短整数...
  • 我删除了评论。现在可以了。请给我几分钟。完美!
【解决方案2】:

您可以读取文本文件并将每个“单词”转换为 int:

with open(the_file, 'r') as f:
    lines = f.read_lines()
    numbers = [int(w) for line in lines for w in line.split()]

然后你必须用structnumbers打包成一个二进制数组:

binary_representation = struct.pack("{}i".format(len(numbers)), *numbers)

如果您希望这些数据以二进制格式写入,则必须在打开目标文件时指定:

with open(target_file, 'wb') as f:
   f.write(binary_representation)

【讨论】:

  • 我同意这种双重列表理解语法更具可读性,但不幸的是,它不起作用。此外,如果你对一个字符串进行迭代,你得到的是字符,而不是单词。
  • 破产了。这是相反的方式。谢谢
【解决方案3】:

不是字节数组

bytearray documentation开始,它只是一个0

作为一个例子,你可以这样初始化它:

bytearray([40,13,123,89,123,4,12,0])
# bytearray(b'(\r{Y{\x04\x0c\x00')

由于整数已经以二进制形式存储,因此您无需进行任何转换。

你的问题现在变成了:你想用2223做什么?

>>> bytearray([2223])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: byte must be in range(0, 256)

uint32 还是 int32 数组?

要读取一个文件,您可以使用:

import re
with open('test.txt') as f:
    numbers = [int(w) for line in f for w in re.split(' +', line)]
    print numbers
    #[40, 13, 123, 89, 123, 2223, 4, 12, 0]

一旦你有一个整数列表,你可以选择相应的低级Numpy data structure,可能是uint32int32

【讨论】:

    【解决方案4】:

    我需要这个 服务器-客户端模块,它的一个功能需要 binary 输入。可以找到不同的节俭类型here

    客户

    myList = [5, 999, 430, 0]
    binL = array.array('l', myList).tostring()
    # call function with binL as parameter
    

    服务器我重构了列表

    k = list(array.array('l', binL))
    print(k)
    [5, 999, 430, 0]
    

    【讨论】:

      【解决方案5】:

      试试这个:

      输入.txt:

      40 13 123
      89 123 2223
      4  12  0
      

      将输入解析为输出的代码:

      with open('input.txt', 'r') as _in:
          nums = map(bin, map(int, _in.read().split())) # read in the whole file, split it into a list of strings, then convert to integer, the convert to binary string
      
      with open('output.txt', 'w') as out:
                out.writelines(map(lambda b: b + '\n', map(lambda n: n.replace('0b', ''), nums))) # remove the `0b` head from the binstrings, then append `\n` to every string in the list, then write to file
      

      输出.txt:

      101000
      1101
      1111011
      1011001
      1111011
      100010101111
      100
      1100
      0
      

      希望对你有帮助。

      【讨论】:

      • 谢谢,但我不想将它作为二进制文件写入新文件,我需要将它保存在二进制对象中。像字节数组左右。但我感谢你的努力。谢谢。
      • @TonyTannous:那你的问题没有意义,而且看起来你并不确切知道要发送什么。
      • @EricDuminil 他知道,但没有合适的条款。
      • @TonyTannous 然后使用ints 的列表。稍后您可以将其转换为您想要的任何内容:D
      猜你喜欢
      • 2018-11-03
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2018-06-20
      • 2023-01-07
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      相关资源
      最近更新 更多