【问题标题】:how to unzip a zipped file in s3如何在s3中解压缩压缩文件
【发布时间】:2021-09-12 08:43:07
【问题描述】:

我在 s3 存储桶的文件夹中有一个压缩文件。我想使用 boto3 解压缩文件。这是我目前的代码。

def unzip_file(path, file_name):
    s3 = boto3.resource('s3', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)
    my_bucket = s3.Bucket(BUCKET)

    lst = list(my_bucket.objects.filter(Prefix=path))
    unzip_path = '/'.join(str(lst[0].key).split('/')[:-1])

    with zipfile.ZipFile(f"{path}/{file_name}", 'r') as zip_ref:
        zip_ref.extractall(unzip_path)

但这只是给出如下错误

Traceback (most recent call last):
  File "download.py", line 153, in <module>
    unzip_file(path, file_name)
  File "download.py", line 32, in unzip_file
    with zipfile.ZipFile(f"{path}/{file_name}", 'r') as zip_ref:
  File "/Users/sashaanksekar/anaconda3/lib/python3.8/zipfile.py", line 1250, in __init__
    self.fp = io.open(file, filemode)
FileNotFoundError: [Errno 2] No such file or directory: 'test_parent/test_num/test.zip'

如何用 python 和 boto3 解压文件?

[编辑1]

我已经编辑了代码,使压缩文件现在在内存中。如何将所有文件提取到 S3 中。

这是我现在的代码

def unzip_file(r, path, file_name):
    s3 = boto3.resource('s3', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)
    my_bucket = s3.Bucket(BUCKET)

    if r.status_code == 200:
        filebytes = BytesIO(r.content)
        file = zipfile.ZipFile(filebytes)

        extract_folder = f"{path}extract_test/"
        
        # extract each file in file.namelist() and save in extract_folder here

【问题讨论】:

  • 你下载了那个文件吗?好像没有。
  • @Marcin 是否有必要将文件下载到我的本地系统?我可以在 AWS 门户中查看压缩文件。我不能运行代码来解压 S3 存储桶本身吗?
  • 不,你不能,因为 S3 不是文件系统,而是对象存储。您必须先将文件下载到本地硬盘或内存中。
  • @Marcin 我已经编辑了代码以将压缩文件保存在内存中。我现在如何提取文件?
  • 看看 .put_object(Body=obj, Bucket=my_bucket, Key=key)。这处理内存中的对象而不是upload_file()。您可能需要使用 Body 来确保正确上传。

标签: python boto3 unzip zipfile


【解决方案1】:

由于我不确定r.content 是什么以及您的函数背后的逻辑,我提供了一个工作示例

import zipfile
from io import BytesIO

import boto3

BUCKET='my-bucket'
key='my.zip'

s3 = boto3.resource('s3')
my_bucket = s3.Bucket(BUCKET)

# mem buffer
filebytes = BytesIO()

# download to the mem buffer
my_bucket.download_fileobj(key, filebytes)

# create zipfile obj
file = zipfile.ZipFile(filebytes)

# extact
file.extractall('/tmp/extract_test')

【讨论】:

  • 这会将文件解压缩到本地系统中的/tmp/extract_test。怎么直接提取到s3桶里?
  • @Sashaank 类似。您必须在本地解压缩,然后将每个解压缩的文件上传到 S3。
  • @Sashaank 如果您使用的是 Linux,您可以使用 github.com/s3fs-fuse/s3fs-fuse 将 S3 模拟为文件系统。这可以简单的下载和上传。
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2011-11-15
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多