【问题标题】:how to generate a binary file如何生成二进制文件
【发布时间】:2022-01-01 21:20:07
【问题描述】:

我正在做一个学校项目,这是我的问题:

生成一个二进制文件,其中包含编码表和 使用 Huffman 编码的文件数据。

首先,我需要从文件中读取数据并创建一棵 Huffman 树,因此我创建了它并且一切正常,但我无法生成二进制文件,因为我拥有的数据是节点而不是对象,所以我不能将数据放入二进制文件中,我收到此错误:

TypeError: a bytes-like object is required, not 'node'

q = {}
a_file = open("george.txt", 'r')
for line in a_file:
    key, value = line.split()

    q[key] = value


class node:
    def __init__(self, freq, symbol, left=None, right=None):
        self.freq = freq

        self.symbol = symbol

        self.left = left

        self.right = right

        self.huff = ''


def printNodes(node, val=''):
    newVal = val + str(node.huff)
    if(node.left):
        printNodes(node.left, newVal)
    if(node.right):
        printNodes(node.right, newVal)

    if(not node.left and not node.right):
        print(f"{node.symbol} -> {newVal}")


chars = ['a', 'b', 'c', 'd', 'e', 'f']

# frequency of characters
freq = [q['a'], q['b'], q['c'], q['d'], q['e'], q['f']]

nodes = []

for x in range(len(chars)):
    nodes.append(node(freq[x], chars[x]))

while len(nodes) > 1:
    nodes = sorted(nodes, key=lambda x: x.freq)

    left = nodes[0]
    right = nodes[1]
    left.huff = 0
    right.huff = 1
    newNode = node(left.freq+right.freq, left.symbol+right.symbol, left, right)
    nodes.remove(left)
    nodes.remove(right)
    nodes.append(newNode)

printNodes(nodes[0])
with open('binary.bin', 'wb') as f:
    f.write(nodes[0])

【问题讨论】:

  • 霍夫曼编码是一种压缩算法。输出文件应小于输入文件。我怀疑给定的答案就是这种情况。

标签: python algorithm


【解决方案1】:

将结构化对象转换为二进制形式的过程称为“序列化”,因此通常要从搜索“python 序列化”开始。它是大多数编程语言不可或缺的一部分,并且有多种形式。 python中事实上的序列化方法称为Pickle,在python packagepickle中。

Pickle 可让您将对象转换为二进制表示,反之亦然,为您处理大量协议细节。

在您的示例中,您有:

with open('binary.bin', 'wb') as f:
    f.write(nodes[0])

您可以像这样将其序列化为二进制形式:

import pickle

with open('binary.bin', 'wb') as f:
    b = pickle.dumps(nodes[0])  # bytes representation of your object
    f.write(b)                  # you can now write the bytes

您也可以使用以下速记方法将所有节点保存在一行中:

pickle.dump('binary.bin', nodes)

反序列化看起来很相似:

with open('binary.bin', 'rb') as f:
    b = f.read()
    node0 = pickle.loads(b)

nodes = pickle.load('binary.bin')

以下是一些相关的帖子:

【讨论】:

  • 我认为这不是 OP 需要的答案。是的,它提供了一个二进制文件,但不,它不会是 Huffman 压缩。由于pickle将Python类型信息存储在文件中,因此文件可能会比原始文件大,因此不会被压缩。
  • 重点,我没有解决霍夫曼编码效率的问题。如果 OP 在此处通过评论确认理解,我将删除此答案以打开它以获得解决该核心问题的答案。 OP 还可以取消选中已接受的答案,以便引出其他答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2017-09-24
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多