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

Append a folder to gzip in memory using python

我有一个从 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 文件的好方法吗?
谢谢

很好地解释了问题

Note that 'a:gz' or 'a:bz2' is not possible. If mode is not suitable to open a certain (compressed) file for reading, ReadError is raised. Use mode 'r' to avoid this. If a compression method is not supported, CompressionError is raised.

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

一个tar 文件由两个全为零的512 字节块终止。要添加更多条目,您需要删除或覆盖末尾的 1024 个字节。如果您然后在那里附加另一个 tar 文件,或者 start 在那里写一个新的 tar 文件,您将有一个包含所有条目的 tar 文件原来两个.

现在我们return到tar.gz。您可以简单地解压缩整个 .gz 文件,像上面那样添加,然后重新压缩整个文件。

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

压缩流由一系列压缩数据“块”组成,每个块的长度都是任意位数。您需要解压缩,但不写出结果,直到到达包含最后 1024 个字节的块。您需要保存该块和任何后续块的解压缩结果,以及块 star 流中的 。然后你可以重新压缩该数据,没有最后 1024 个字节,starting 在那个字节。

完成压缩,并写出从 CRC 和长度中删除 1024 个零的 gzip 尾部。 (有一种方法可以从 CRC 中取消零。)现在你有一个完整的前一个 .tar.gz 文件的 gzip 流,但删除了最后 1024 个字节的零。

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