【问题标题】:How to zip files in Amazon s3 Bucket and get its URL如何在 Amazon s3 Bucket 中压缩文件并获取其 URL
【发布时间】:2020-11-25 04:02:02
【问题描述】:

我在 Amazon s3 存储桶中有一堆文件,我想压缩这些文件并使用 Java Spring 通过 S3 URL 下载获取内容。

【问题讨论】:

  • 您能说明一下您的要求吗? “将这些亚马逊 URL 压缩到 Zip 中”是什么意思?您的意思是您希望在包含 URL 列表的 Amazon S3 存储桶中创建一个新对象?或者您希望从多个现有文件创建一个 Zip 文件?请编辑您的问题以提供更多信息,以便我们为您提供帮助。
  • 先生,我在 Amazon s3 存储桶中有大量文件。我只想从这些文件中创建一个 Zip 文件并直接从存储桶中获取单个文件

标签: java spring amazon-web-services amazon-s3


【解决方案1】:

S3 不是文件服务器,也不提供操作系统文件服务,例如数据操作。

如果有很多“巨大”的文件,你最好的选择是

  1. 启动一个简单的 EC2 实例
  2. 将所有这些文件下载到 EC2 实例,压缩它们,然后使用新的对象名称将其重新上传回 S3 存储桶

是的,您可以使用 AWS lambda 做同样的事情,但 lambda 的执行超时限制为 900 秒(15 分钟)(因此建议分配更多 RAM 以提高 lambda 执行性能)

从 S3 到本地区域 EC2 实例等服务的流量是免费的。

如果您的主要目的只是读取使用 EC2/etc 服务在同一 AWS 区域内的那些文件,那么您不需要这个额外的步骤。直接访问文件即可。

(更新): 正如@Robert Reiz 所提到的,现在您也可以使用 AWS Fargate 来完成这项工作。

注意:

建议使用 AWS API 访问和共享文件。如果您打算公开共享文件,则必须认真考虑安全问题并施加下载限制。 AWS 向互联网传输的流量从不便宜。

【讨论】:

  • Lambda 执行超时设置可以设置为 15 分钟而不是 300 秒,正如我在仪表板上看到的那样。
  • EC2 是 AWS 上最昂贵的服务之一。我会推荐 ECS Fargate,因为它具有 EC2 的所有优点,但成本要低得多。如果您需要定期运行此类任务,您甚至可以在 ECS Fargate 上创建一个计划任务,这将每 X 小时或几天触发一个 Docker 容器。
【解决方案2】:

您好,我最近必须为我的应用程序执行此操作 - 通过用户可以下载的 url 链接提供 zip 格式的文件包。

简而言之,首先使用 BytesIO 方法创建一个对象,然后使用 ZipFile 方法通过迭代所有 s3 对象来写入该对象,然后对该 zip 对象使用 put 方法并为其创建一个预置 url。

我使用的代码如下所示:

首先调用这个函数获取zip对象,ObjectKeys就是你需要放入zip文件的s3对象。


def zipResults(bucketName, ObjectKeys):
    buffer = BytesIO()
    with zipfile.ZipFile(buffer, 'w', compression=zipfile.ZIP_DEFLATED) as zip_file:
        for ObjectKey in ObjectKeys:
            objectContent = S3Helper().readFromS3(bucketName, ObjectKey)
            fileName = os.path.basename(ObjectKey)
            zip_file.writestr(fileName, objectContent)

    buffer.seek(0)
    return buffer

然后调用这个函数,key就是你给你的zip对象的key:

def uploadObject(bucketName, body, key):
    s3client = AwsHelper().getClient("s3")
    try:
        response = s3client.put_object(
            Bucket=bucketName,
            Body=body,
            Key=key
        )
    except ClientError as e:
        logging.error(e)
        return None

    return response

当然,你需要 io、zipfile 和 boto3 模块。

【讨论】:

    【解决方案3】:

    如果您需要压缩 S3 中的单个文件(对象),则可以通过迂回的方式进行。您可以定义指向 S3 存储桶的 CloudFront 端点,然后让 CloudFront 在输出时压缩内容:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html

    【讨论】:

    • 这不适用于大于 10MB 的文件。是否有任何其他自动化方式可以在 AWS 上提供压缩文件?
    • 只是在这里吐口水,但是您可以创建一个 API 网关,向可以处理文件的 lambda 函数发送请求(我认为您被授予 5GB tmp 空间来进行文件处理),复制通过 lambda 归档回 s3 存储桶,确定该路径,并将该路径的下载 url 作为响应返回给客户端(通过网关)。
    • 抱歉,应该是 500MB tmp 空间,而不是 5GB,虽然我做过的一次培训说 5GB.... 从未测试过,所以不知道会发生什么...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2017-05-04
    • 2021-09-12
    • 2016-03-31
    相关资源
    最近更新 更多