使用iter_chunks()从S3中解压缩字节块。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用iter_chunks()从S3中解压缩字节块。相关的知识,希望对你有一定的参考价值。

我遇到了一个问题,就是我在从S3中使用 iter_chunks() 方法从 boto3. 逐块解压缩文件的策略源于 本期.

代码如下。

dec = zlib.decompressobj(32 + zlib.MAX_WBITS)
for chunk in app.s3_client.get_object(Bucket=bucket, Key=key)["Body"].iter_chunks(2 ** 19):
    data = dec.decompress(chunk)
    print(len(chunk), len(data))

# 524288 65505
# 524288 0
# 524288 0
# ...

这段代码最初打印出的是 65505 之后的每一次迭代都以0跟随。我的理解是,这段代码应该解压每个压缩块,然后打印未压缩版本的长度。

我是否遗漏了什么?

答案

似乎你的输入文件是块状的gzip(bgzip)。http:/www.htslib.orgdocbgzip.html )因为你有一个65k的数据块被解码。

GZip文件可以被连接在一起 ( 见 https:/www.gnu.orgsoftwaregzipmanualgzip.html#Advanced-usage),而Block GZip利用这一点将同一文件的区块进行串联,这样通过使用关联索引,只需要对包含感兴趣信息的特定区块进行解码。

所以要对一个块状gzip文件进行流式解码,需要使用一个块的剩余数据来启动一个新的块。例如

# source is a block gzip file see http://www.htslib.org/doc/bgzip.html
dec = zlib.decompressobj(32+zlib.MAX_WBITS)
for chunk in raw:
    # decompress this chunk of data
    data = dec.decompress(chunk)
    # bgzip is a concatenation of gzip files
    # if there is stuff in this chunk beyond the current block
    # it needs to be processed
    while len(dec.unused_data):
        # end of one block
        leftovers = dec.unused_data
        # create a new decompressor
        dec = zlib.decompressobj(32+zlib.MAX_WBITS)
        #decompress the leftovers
        data = data+dec.decompress(leftovers)
    # TODO handle data

以上是关于使用iter_chunks()从S3中解压缩字节块。的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 中解压缩使用 Lempel-Ziv Haruyasu 算法压缩的字节?

AWS Lambda (Python) 无法在 S3 中解压缩和存储文件

在C#中解压缩字节数组

使用 Ruby 从二进制字符串中解包一点

使用 ZipFile 类从多个文件的 zip 存档中解压缩文件

使用 pathlib 模块从 rglob() 方法的输出中解压缩所有项目 [关闭]