当前位置:  开发笔记 > 编程语言 > 正文

从Python设置gzip时间戳

如何解决《从Python设置gzip时间戳》经验,为你挑选了2个好方法。

我对使用Python gzip模块压缩数据感兴趣.碰巧我希望压缩输出是确定性的,因为通常情况下这通常是一个非常方便的属性 - 如果一些非gzip感知的进程要在输出中寻找变化,比如说,或者如果输出将以加密方式签名.

不幸的是,每次输出都不同.据我所知,唯一的原因是gzip头中的timestamp字段,Python模块总是填充当前时间.我不认为你真的被允许有一个没有时间戳的gzip流,这太糟糕了.

在任何情况下,Python gzip模块的调用者似乎都没有办法提供底层数据的正确修改时间.(实际gzip程序似乎尽可能使用输入文件的时间戳.)我想这是因为基本上唯一关心时间戳的是gunzip写入文件时的命令 - 现在,我,因为我想要确定性的输出.这是不是要求太过分了?

还有其他人遇到过这个问题吗?

gzip使用Python的任意时间戳来获取某些数据的最不可靠的方法是什么?



1> Ned Batcheld..:

是的,你没有任何漂亮的选择.在_write_gzip_header中使用此行写入时间:

write32u(self.fileobj, long(time.time()))

由于它们没有为您提供覆盖时间的方法,因此您可以执行以下操作之一:

    从GzipFile派生一个类,并将该_write_gzip_header函数复制到派生类中,但在这一行中具有不同的值.

    导入gzip模块后,将新代码分配给其时间成员.您将基本上在gzip代码中提供名称时间的新定义,因此您可以更改time.time()的含义.

    复制整个gzip模块,并将其命名为my_stable_gzip,并更改所需的行.

    将CStringIO对象作为fileobj传递,并在gzip完成后修改字节流.

    编写一个伪文件对象来跟踪写入的字节,并将所有内容传递给一个真实的文件,除了您自己编写的时间戳的字节.

这是选项#2(未经测试)的示例:

class FakeTime:
    def time(self):
        return 1225856967.109

import gzip
gzip.time = FakeTime()

# Now call gzip, it will think time doesn't change!

在不依赖于gzip模块内部(未经测试)的情况下,选项#5可能是最干净的:

class GzipTimeFixingFile:
    def __init__(self, realfile):
        self.realfile = realfile
        self.pos = 0

    def write(self, bytes):
        if self.pos == 4 and len(bytes) == 4:
            self.realfile.write("XYZY")  # Fake time goes here.
        else:
            self.realfile.write(bytes)
        self.pos += len(bytes)



2> 小智..:

从Python 2.7开始,您可以指定gzip标头中要使用的时间。NB文件名也包含在标题中,也可以手动指定。

import gzip

content = b"Some content"
f = open("/tmp/f.gz", "wb")
gz = gzip.GzipFile(fileobj=f,mode="wb",filename="",mtime=0)
gz.write(content)
gz.close()
f.close()

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有