微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用python将文件夹附加到内存中的gzip

如何解决使用python将文件夹附加到内存中的gzip

我有一个从 s3 下载的 tar.gz 文件,我将它加载到内存中,我想添加一个文件夹并最终将其写入另一个 s3。
我一直在尝试不同的方法

from io import BytesIO
import gzip
buffer = BytesIO(zip_obj.get()["Body"].read())
im_memory_tar = tarfile.open(buffer,mode='a')

上面出现错误ReadError: invalid header

使用以下方法

im_memory_tar = tarfile.open(fileobj=buffer,mode='a')
im_memory_tar.add(name='code_1',arcname='code') 

内容似乎被覆盖了。
您知道将文件夹附加到 tar.gz 文件的好方法吗?
谢谢。

解决方法

很好地解释了问题 how-to-append-a-file-to-a-tar-file-use-python-tarfile-module

请注意,'a:gz' 或 'a:bz2' 是不可能的。如果 mode 不适合打开某个(压缩)文件进行读取,则会引发 ReadError。使用模式 'r' 来避免这种情况。如果不支持压缩方法,则会引发 CompressionError。

,

首先我们需要考虑如何附加到 tar 文件中。让我们暂时搁置压缩。

一个 tar 文件由两个全零的 512 字节块终止。要添加更多条目,您需要删除或覆盖最后的 1024 个字节。如果您随后在那里附加另一个 tar 文件,或者开始在那里写入一个新的 tar 文件,您将拥有一个包含原始两个条目的单个 tar 文件。

现在我们回到 tar.gz。您可以简单地解压缩整个 .gz 文件,按照上述方法进行追加,然后重新压缩整个文件。

避免解压缩和重新压缩相当困难,因为我们必须以某种方式从压缩流的末尾删除最后 1024 个字节的零。这是可能的,但您需要了解 deflate 压缩流的内部结构。

deflate 流由一系列压缩数据“块”组成,每个块的长度为任意位数。您需要在不写出结果的情况下解压缩,直到到达包含最后 1024 个字节的块。您需要保存该块和任何后续块的解压缩结果,以及该块开始的流中的。然后您可以重新压缩该数据,从该字节开始,去掉最后 1024 个字节。

完成压缩,写出gzip预告片,去掉CRC和长度的1024个零。 (有一种方法可以从 CRC 中删除零。)现在您有一个完整的 gzip 流,用于前一个 .tar.gz 文件,但删除了最后 1024 个字节的零。

由于两个 gzip 流的连接本身就是一个有效的 gzip 流,您现在可以直接连接第二个 .tar.gz 文件或在那里开始写入新的 .tar.gz 流。您现在有一个单一的、有效的 .tar.gz 流,其中包含来自两个原始来源的条目。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。