【问题标题】:Using zstandard to compress a file in Python在 Python 中使用 zstandard 压缩文件
【发布时间】:2020-10-22 18:23:57
【问题描述】:

所以我使用了zstandard python 库,并且我编写了一个帮助类和函数来使用上下文来解压缩文件。

class ZstdReader:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.f = open(self.filename, 'rb')
        dctx = zstd.ZstdDecompressor()
        reader = dctx.stream_reader(self.f)
        return io.TextIOWrapper(reader, encoding='utf-8')

    def __exit__(self, *a):
        self.f.close()
        return False

def openZstd(filename, mode='rb'):
    if 'w' in mode:
        return ZstdWriter(filename)
    return ZstdReader(filename)

这非常有效,允许我在使用文件f 进行json 转储和加载之前只使用with openZstd('filename.zst', 'rb') as f:。 但是,我在将其推广到写作时遇到了问题,我尝试以与迄今为止相同的方式遵循文档,但有些东西不起作用。这是我尝试过的:

class ZstdWriter:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.f = open(self.filename, 'wb')
        ctx = zstd.ZstdCompressor()
        writer = ctx.stream_writer(self.f)
        return io.TextIOWrapper(writer, encoding='utf-8')

    def __exit__(self, *a):
        self.f.close()
        return False

当我使用此类打开一个文件并执行json.dump([], f) 时,由于某种原因,该文件最终为空。我想其中一个步骤是吞下我的输入,但不知道它可能是什么。

【问题讨论】:

  • 我不熟悉zstandard,但我想ctxwriter 对象需要有明确的close()flush() 执行某种操作在他们身上,以确保任何缓冲的数据都被实际写出。
  • @jasonharper 如果我刷新包装器、编写器和文件描述符,则文件非空并解压缩正确的内容,但 zstd CLI 抱怨过早结束仍然...
  • 来自文档:“如果未调用 flush(FLUSH_FRAME),则发出的数据不会构成完整的 zstd 框架,并且此数据的消费者可能会抱怨输入格式错误。”您是否使用不同的参数调用flush()

标签: python zstandard


【解决方案1】:

正如 jasonharper 在 cmets 中所建议的,您必须同时刷新 io 包装器和编写器本身,如下所示:

s = json.dumps({})
iw = io.TextIOWrapper(writer, encoding="utf-8")
iw.write(s)

iw.flush()
writer.flush(zstd.FLUSH_FRAME)
f.close()

这会导致数据在文件中,并且文件是完整的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    相关资源
    最近更新 更多