我有以下功能:
def save(msg):
with gzip.open("ircbot.log.gz", "ab") as f:
f.write(msg+'\n')
f.close()
return "Succesfully logged: "+msg
我想将每个msg添加到.log文件中,但它不起作用,只保存第一个msg。
例如,在调用这些函数之后:
save('first')
save('second')
save('third')
.log文件只包含'first'。
对于简单的.txt文件,它可以正常工作。 Gzip不支持追加文件吗?
答案 0 :(得分:3)
连接gzip流以生成可提取的gzip文件(即每条消息后f.close()
) 正如您所发现的那样工作。这是因为gzip标准要求兼容的解压缩器在解码当前的gzip流之后寻找另一个gzip流。但是,假设您的邮件相对较短,例如一行或两行,然后生成的gzip文件将更大,不小于带有消息的简单文本文件。每条消息至少会有一个18字节的gzip头和尾部的开销,数据可能会扩展5个字节,每个消息增加23个字节。
在每条消息之后不使用f.close()
的替代方案将导致数据的实际压缩,通过编写单个gzip流,其中后续消息的压缩可以利用先前消息的冗余。然而,在做最终调用f.close()
之前,这有一个缺点是永远不会有一个完整和正确的gzip文件。此外,根本不会写入消息(再次,如果它们很短),直到累积足够的消息来压缩块。然后一串将被写入一个爆发,文件将再次等待更多的累积。
有一个解决方案,但我认为python没有足够的zlib接口来允许它。您可以查看C,gzlog.h和gzlog.c中的示例,该示例立即将日志条目写入gzip文件,并始终使日志文件保持完整且正确的状态。
答案 1 :(得分:0)
好的,我明白了。
我使用Altap Salmander提取.gz并查看日志文件(F3功能)。
当我使用7zip在经典资源管理器中提取gz文件时,所有的消息都在那里。
答案 2 :(得分:0)
为我工作,没有额外的f.close()
,Linux,python-2.7,这两个文件都是由这个脚本创建的gzip文件和一个由常规gzip命令创建的gzip文件。