【问题标题】:Append a folder to gzip in memory using python使用python将文件夹附加到内存中的gzip
【发布时间】:2021-01-08 12:28:45
【问题描述】:

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

【问题讨论】:

    标签: python amazon-web-services amazon-s3 gzip tarfile


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-08-08
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2014-06-07
        • 1970-01-01
        • 2017-05-22
        • 2020-11-01
        • 2022-10-14
        相关资源
        最近更新 更多