首页 > 解决方案 > 从 S3 读取 ZIP 存档,并将未压缩版本写入新存储桶

问题描述

我有一个应用程序,用户可以在其中上传资源的 ZIP 存档。我的应用程序处理上传并将其保存到 S3。在某个时候,我想运行一个转换来读取这个 S3 存储桶,解压缩它,然后将它写入一个新的 S3 存储桶。这一切都发生在节点服务上。

我正在使用解压缩库来处理解压缩。这是我的初始代码。

    async function downloadFromS3() {
  let s3 = new AWS.S3();
  try {
    const object = s3
      .getObject({
        Bucket: "zip-bucket",
        Key: "Archive.zip"
      })
      .createReadStream();

    object.on("error", err => {
      console.log(err);
    });

    await streaming_unzipper(object, s3);
  } catch (e) {
    console.log(e);
  }
}

async function streaming_unzipper(s3ObjectStream, s3) {
  await s3.createBucket({ Bucket: "unzip-bucket" }).promise();
  const unzipStream = s3ObjectStream.pipe(unzipper.Parse());
  unzipStream.pipe(
    stream.Transform({
      objectMode: true,
      transform: function(entry, e, next) {
        const fileName = entry.path;
        const type = entry.type; // 'Directory' or 'File'
        const size = entry.vars.uncompressedSize; // There is also compressedSize;
        if (type === "File") {
          s3.upload(
            { Bucket: "unzip-bucket", Body: entry, Key: entry.path },
            {},
            function(err, data) {
              if (err) console.error(err);
              console.log(data);
              entry.autodrain();
            }
          );
          next();
        } else {
          entry.autodrain();
          next();
        }
      }
    })
  );

这段代码是有效的,但我觉得它可以被优化。理想情况下,我想通过管道传输下载流->解压缩流->上传流。因此,当块解压缩时,它们会被上传到 S3,而不是等待完全填充的 uzip 完成然后上传。

我遇到的问题是我需要文件名(设置为 S3 密钥),我只有在解压缩后才有。在我开始上传之前。

有什么好的方法可以创建到 S3 的流式上传。以临时 ID 启动,在完整流完成后用最终名称重写。

标签: node.jsamazon-s3nodejs-stream

解决方案


推荐阅读