来自 S3 文件的 Zip 文件

Zip File from S3 files

Ruby '2.7.4'

Rails '~> 5.2.2'

我可以访问包含多种类型文件的 S3 存储桶,我正在尝试这样做

  1. 下载到内存
  2. 将它们全部放在一个 zip 文件中
  3. 将此 zip 文件上传到某个 S3 存储桶

我已经在网上调查了几个问题,但都没有成功。 具体来说,我正在尝试使用 rubyzip gem,但无论我做什么,我总是以错误消息结束:'no implicit conversion of StringIO into String'

这是我当前代码的摘要

gem 'rubyzip', require: 'zip'
require 'zip'

bucket_name = 'redacted'
zip_filename = "My final complete zip file.zip"
s3_client = Aws::S3::Client.new(region: 'eu-west-3')
s3_resource = Aws::S3::Resource.new(region: 'eu-west-3')
bucket = s3_resource.bucket(bucket_name)
s3_filename = 's3_file_name'
s3_file = s3_client.get_object(bucket: bucket_name, key: s3_filename)
file = s3_file.body

此时,我正好有 一个 文件,采用 StringIO 格式。 但是请记住,我正在尝试使用多个文件重现此内容,这意味着我想将多个文件捆绑在一个最终的 zip 文件中。 我无法将此文件放入 zip and/or 将 zip 放回 s3。

尝试 N°1

stringio = Zip::OutputStream.write_buffer do |zio|
  zio.put_next_entry("test1.zip")
  zio.write(file)
end

stringio.rewind
binary_data = stringio.sysread

错误信息: no implicit conversion of StringIO into String

尝试 N°2

zip_file_name = 'my_test_file_name.zip'
File.open(zip_file_name, 'w') { |f| f.puts(file.rewind && file.read) }

final_zip = Zip::File.open(zip_filename, create: true) do |zipfile|
  zf = Zip::File.new(file, create: true, buffer: true)
  zipfile.add(zf.to_s, zip_file_name)
end

really_final_zip = Zip::File.new(final_zip, create: true, buffer: true)

new_object = bucket.object(zip_file_name)
new_object.put(body: final_zip)

错误信息: expected params[:body] to be a String or IO like object that supports read and rewind, got value #<Zip::Entry:0x0000558a06ff42a0 如果不是最后一行,我写 new_object.put(body: final_zip.to_s) 在 S3 中创建一个文本文件(而不是 zip),内容为 #<StringIO:0x0000558a06c8c8d8>

需要从文件中读取字节,所以...

改变 s3_file.bodys3_file.body.read