【问题标题】:Appending to gzip file in Python doesnt work在 Python 中附加到 gzip 文件不起作用
【发布时间】:2012-12-22 13:00:50
【问题描述】:

我有以下功能:

def save(msg):
    with gzip.open("ircbot.log.gz", "ab") as f:
        f.write(msg+'\n')
        f.close()
        return "Succesfully logged: "+msg

我想将每个味精添加到 .log 文件中,但它不起作用,只保存第一个味精。

例如在调用这些函数之后:

save('first')
save('second')
save('third')

.log 文件只包含“first”。

对于简单的 .txt 文件,它可以正常工作。 Gzip 不支持附加到文件?

【问题讨论】:

  • 注意,当使用文件作为上下文管理器时,您不需要/不应该调用close
  • 我无法重现这个。当我运行您的函数时(在修复第一行中明显的语法错误之后),我得到了完全期望的行为。语法错误表明这不是您的实际代码。
  • 我只复制了函数逻辑。我添加了函数名来演示如何调用它,这就是我忘记 ':' 的原因。
  • @delnan 调用 GzipFile 对象的 close() 方法不会关闭 fileobj,... --python.org;所以在这里它实际上并不重要

标签: python io gzip


【解决方案1】:

连接 gzip 流以生成可提取的 gzip 文件(即每条消息后的 f.close()确实工作,正如您发现的那样。这是因为 gzip 标准需要兼容的解压缩器在解码当前的 gzip 流后查找另一个 gzip 流。但是,假设您的消息相对较短,例如一两行,然后生成的 gzip 文件会更大,而不是比包含消息的简单文本文件小。每条消息至少会有 18 个字节的 gzip 标头和尾部的开销,并且数据可能会扩展 5 个字节,每条消息增加 23 个字节。

在每条消息之后不使用f.close() 的替代方案将导致数据的真正压缩,方法是编写单个 gzip 流,在此压缩后面的消息可以利用早期消息的冗余。然而,这样做的缺点是在你最终调用f.close() 之前永远不会有一个完整且正确的gzip 文件。此外,消息根本不会被写入(如果它们很短,则再次写入),直到积累了足够的信息来压缩一个块。然后会一串串的写入,文件会再次等待更多的积累。

对此有一个解决方案,但我认为 python 没有足够完整的 zlib 接口来允许它。您可以查看 C 语言中的示例 gzlog.hgzlog.c,它们会立即将日志条目写入 gzip 文件,并且始终使日志文件处于完整且正确的状态。

【讨论】:

    【解决方案2】:

    好的,我想通了。

    我使用 Altap Salmander 提取 .gz 并查看日志文件(F3 功能)。

    当我在经典资源管理器中使用 7zip 提取 gz 文件时,所有消息都在那里。

    【讨论】:

      【解决方案3】:

      为我工作,没有额外的f.close(),Linux,python-2.7,都带有由该脚本创建的 gzip 文件和由常规 gzip 命令创建的 gzip 文件。

      【讨论】:

        猜你喜欢
        • 2013-08-08
        • 1970-01-01
        • 2013-11-03
        • 2017-09-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2021-01-04
        • 1970-01-01
        相关资源
        最近更新 更多