以流式方式在s3中解压嵌套的tar文件

dy1byipe  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(418)

我在s3中有一个很大的tar文件(10s的gbs)。它包含许多tar.gz文件。
我可以使用以下内容循环浏览大文件的内容

s3_client = boto3.client('s3')
    input = s3_client.get_object(Bucket=bucket, Key=key)

    with tarfile.open(fileobj=input['Body'],mode='r|') as tar:
        print(tar) -- tarinfo

但是,我似乎无法从内部tar.gz文件打开文件内容。
我希望能够以流式方式完成这项工作,而不是将整个文件加载到内存中。
我试过做类似的事情

tar.extract_file(tar.next)

但我不确定这个类似文件的对象是如何可读的。
---编辑
在@larsks的帮助下,我有了进一步的进展。

with tarfile.open(fileobj=input_tar_file['Body'],mode='r|') as tar:
        for item in tar:
            m = tar.extractfile(item)
            if m is not None:
                with tarfile.open(fileobj=m, mode='r|gz') as gz:
                    for data in gz:
                        d = gz.extractfile(data)

但是如果我在d上调用.read()。它是空的。如果我遍历d.raw.fileobj.read(),就会有数据。但是当我写出来的时候,它是嵌套tar.gz中所有文本文件的数据,而不是一个接一个的数据。

bnl4lu3b

bnl4lu3b1#

的返回值 tar.extractfile 是一个“类似文件的对象”,就像 input['Body'] . 这意味着您可以将其传递给 tarfile.open . 下面是一个打印嵌套存档内容的简单示例:

import tarfile

with open('outside.tar', 'rb') as fd:
    with tarfile.open(fileobj=fd, mode='r') as outside:
        for item in outside:
            with outside.extractfile(item) as inside:
                with tarfile.open(fileobj=inside, mode='r') as inside_tar:
                    for item in inside_tar:
                        data = inside_tar.extractfile(item)
                        print('content:', data.read())

这里的“外部”文件是一个实际的文件,而不是来自s3 bucket的文件;但我先把它打开,这样我们还可以进去 fileobj 打开外部存档时。
代码遍历外部存档的内容( for item in outside ),而对于这些项目中的每一项:
使用打开文件 outside.extractfile() 将其作为参数传递给 fileobj 参数 tarfile.open 提取嵌套文件中的每个项

相关问题