我在使用 boto3
中的 iter_chunks()
方法解压缩从 S3 读取的字节 block 时遇到问题。逐 block 解压文件的策略源自this issue .
代码如下:
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。我的理解是,这段代码应该解压缩每个压缩 block ,然后打印未压缩版本的长度。
我有什么遗漏吗?
最佳答案
您的输入文件似乎是 block gzip (bgzip http://www.htslib.org/doc/bgzip.html ),因为您解码了 65k 数据 block 。
GZip 文件可以连接在一起(参见 https://www.gnu.org/software/gzip/manual/gzip.html#Advanced-usage ),并且 Block GZip 使用它来连接同一文件的 block ,这样通过使用关联的索引,只需解码包含感兴趣信息的特定 block 。
因此,要对 block gzip 文件进行流式解码,您需要使用一个 block 中的剩余数据来开始一个新 block 。例如
# 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
关于python - 使用 iter_chunks() 从 S3 中解压缩字节 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61048597/