如何在Amazon s3 Bucket中压缩文件并获取其URL

jef*_*yan 4 java spring amazon-s3 amazon-web-services

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

moo*_*oot 19

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

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

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

是的,您可以使用AWS lambda执行相同的操作,但lambda的执行时间限制为300秒.

从S3到本地EC2实例和等服务的流量是免费的.

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

注意 :

建议使用AWS API访问和共享文件.如果您打算公开共享该文件,则必须认真研究安全问题并实施下载限制.AWS流向互联网并不便宜.


jav*_*vrd 6

将它们压缩到您的端,而不是在 AWS 中执行,最好是在前端,直接在用户浏览器上执行。您可以在 JavaScript 中流式传输多个文件的下载,使用该流创建 zip 并将该 zip 保存在用户磁盘上。

将压缩移至前端的优点:

  • 您可以将其与 S3 URL、一堆预签名链接一起使用,甚至可以混合来自不同来源的内容,有些来自 S3,有些来自其他地方。
  • 您不必浪费 lambda 内存,也不必启动 EC2 fargate 实例,这样可以节省资金。让用户计算机为您做这件事。
  • 改善用户体验 - 无需等待 zip 创建完成即可开始下载,只需在创建 zip 的同时开始下载即可。

StreamSaver对于此目的很有用,但在其压缩示例(将多个文件保存为 zip)中,文件大小受到小于 4GB 的限制,因为它不实现 zip64。您可以将 StreamSaver 与支持 zip64 的client-zip结合起来,与类似的东西(我还没有测试过):

import { downloadZip } from 'client-zip';
import streamSaver from 'streamsaver';
const files = [
  {
    'name': 'file1.txt',
    'input': await fetch('test.com/file1')
  },
  {
    'name': 'file2.txt',
    'input': await fetch('test.com/file2')
  },
]
downloadZip(files).body.pipeTo(streamSaver.createWriteStream('final_name.zip'));
Run Code Online (Sandbox Code Playgroud)

如果您选择此选项,请记住,如果您在存储桶中启用了 CORS,则需要在AllowedOrigins存储桶的 CORS 配置字段中添加完成压缩的前端 URL。

关于性能: 正如 @aviv-day 在评论中抱怨的那样,这并不适合所有场景。Client-zip 库有一个基准,可以让您了解这是否适合您的场景。一般来说,如果你有一大堆小文件(我没有关于这里大文件的数字,但我会说 100 到 1000 之间的数字),仅仅压缩它就会花费很多时间,而且耗尽最终用户的CPU。另外,如果您为所有用户提供同一组压缩文件,最好将其压缩并显示为已压缩的文件。在前端使用这种压缩方法可以很好地处理有限的一小组文件,这些文件可以根据用户对下载内容的偏好进行动态更改。我没有真正测试过这个,我真的认为瓶颈将是网络速度而不是压缩过程,因为它是动态发生的,我真的不认为具有大量文件的场景实际上是一个问题。如果有人有这方面的基准,很高兴与我们分享!