微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我在 s3 中有一个很大的 tar 文件(10s 的 GB)。它包含许多 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 中所有文本文件的数据,而不是一个一个

解决方法

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 存储桶;但我先打开它以便我们仍然 打开外部存档时传入 fileobj

代码遍历外部存档 (for item in outside) 的内容,并针对以下每个项目:

  • 使用outside.extractfile()
  • 打开文件
  • 将其作为参数传递给 fileobj 参数 tarfile.open
  • 提取嵌套 tarfile 中的每个项目

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。