Как скопировать файл между сегментами с помощью aws-s3 или aws-sdk gem в ruby ​​on rails

В документации aws-s3 сказано:

  # Copying an object
  S3Object.copy 'headshot.jpg', 'headshot2.jpg', 'photos'

Но как мне скопировать heashot.jpg из ведра photos в ведро archive например

Спасибо!

Деб


person deb    schedule 11.08.2010    source источник


Ответы (9)


Gem AWS-SDK. S3Object#copy_to

Copies data from the current object to another object in S3.
S3 handles the copy so the client does not need to fetch the 
data and upload it again. You can also change the storage 
class and metadata of the object when copying.

Он использует метод copy_object internal, поэтому функция копирования позволяет копировать объекты внутри или между корзинами S3 и при необходимости заменять метаданные, связанные с объектом в процессе.

Стандартный метод (загрузка/выгрузка)

введите здесь описание изображения

Метод копирования

введите здесь описание изображения

Пример кода:

require 'aws-sdk'

AWS.config(
  :access_key_id     => '***',
  :secret_access_key => '***',
  :max_retries       => 10
)

file     = 'test_file.rb'
bucket_0 = {:name => 'bucket_from', :endpoint => 's3-eu-west-1.amazonaws.com'}
bucket_1 = {:name => 'bucket_to',   :endpoint => 's3.amazonaws.com'}

s3_interface_from = AWS::S3.new(:s3_endpoint => bucket_0[:endpoint])
bucket_from       = s3_interface_from.buckets[bucket_0[:name]]
bucket_from.objects[file].write(open(file))

s3_interface_to   = AWS::S3.new(:s3_endpoint => bucket_1[:endpoint])
bucket_to         = s3_interface_to.buckets[bucket_1[:name]]
bucket_to.objects[file].copy_from(file, {:bucket => bucket_from})
person Anatoly    schedule 02.05.2012
comment
Помните об ограничении AWS S3: 100 запросов в секунду во всех регионах для загрузки/выгрузки обоих вызовов. - person Anatoly; 09.04.2014

Используя драгоценный камень right_aws:

# With s3 being an S3 object acquired via S3Interface.new
# Copies key1 from bucket b1 to key1_copy in bucket b2:
s3.copy('b1', 'key1', 'b2', 'key1_copy')

Подвох, с которым я столкнулся, заключается в том, что если у вас есть pics/1234/yourfile.jpg, bucket будет только pics, а key будет 1234/yourfile.jpg

Я получил ответ здесь: Как копировать файлы между сегментами с помощью s3 из приложения rails?

person deb    schedule 11.08.2010

При использовании copy_from или copy_to из AWS SDK gem есть три вещи, которые не копируются по умолчанию: ACL, класс хранения или шифрование на стороне сервера. Вам нужно указать их как опции.

from_object.copy_to from_object.key, {:bucket => 'new-bucket-name', :acl => :public_read}

https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/s3/s3_object.rb#L904

person Greg Benedict    schedule 19.07.2013
comment
Вы уверены, что этот метод охватывает вопрос? Автор специально просит копию между двумя ведрами. - person Tim Lawrenz; 19.12.2020

Для тех, кто все еще ищет, у AWS есть документация для этого. На самом деле с драгоценным камнем aws-sdk это очень просто:

bucket = Aws::S3::Bucket.new('source-bucket')
object = bucket.object('source-key')

object.copy_to(bucket: 'target-bucket', key: 'target-key')
person rigdonmr    schedule 06.09.2017

Вот простой класс ruby ​​для копирования всех объектов из одного сегмента в другой: /edwardsharp/d501af263728eceb361ebba80d7fe324

person esharp    schedule 10.05.2016

Несколько изображений можно легко скопировать с помощью aws-sdk gem следующим образом:

require 'aws-sdk'

image_names = ['one.jpg', 'two.jpg', 'three.jpg', 'four.jpg', 'five.png', 'six.jpg']
Aws.config.update({
    region: "destination_region", 
    credentials: Aws::Credentials.new('AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY')
})
image_names.each do |img|
    s3 = Aws::S3::Client.new()
    resp = s3.copy_object({
      bucket: "destinationation_bucket_name", 
      copy_source: URI.encode_www_form_component("/source_bucket_name/path/to/#{img}"), 
      key: "path/where/to/save/#{img}" 
    })      
end

Если у вас слишком много изображений, рекомендуется перевести процесс копирования в фоновое задание.

person techdreams    schedule 07.02.2020

Я считаю, что для копирования между ведрами вы должны прочитать содержимое файла из исходного ведра, а затем записать его обратно в целевое ведро через пространство памяти вашего приложения. Это показано во фрагменте с использованием aws-s3 здесь и другого подхода с использованием right_aws здесь

person bjg    schedule 11.08.2010
comment
Я хотел бы использовать этот фрагмент для aws-s3, но у меня возникли проблемы с инициализацией класса AmazoneS3Asset. Просто поместить фрагмент, определяющий класс, в config/initializers? - person deb; 11.08.2010
comment
Я нашел ответ на свой комментарий здесь stackoverflow. ком/вопросы/1146946/ - person deb; 11.08.2010
comment
очевидно, у right_aws есть эта функция, мне не нужно было добавлять фрагмент. Я разместил больше информации в ответе ниже - person deb; 11.08.2010

Gem aws-s3 не имеет возможности копировать файлы между сегментами без перемещения файлов на локальный компьютер. Если это приемлемо для вас, то следующее будет работать:

AWS::S3::S3Object.store 'dest-key', open('http://url/to/source.file'), 'dest-bucket'
person Jared    schedule 18.08.2011
comment
aws теперь поддерживает это, драгоценный камень также. - person Ivailo Bardarov; 14.12.2018
comment
Да, этот ответ устарел. - person Jared; 21.12.2018

Я столкнулся с той же проблемой, что и у вас, поэтому я клонировал исходный код для AWS-S3 и создал ветку с методом copy_to, который позволяет копировать между сегментами, которые я объединял в свои проекты и использовал, когда мне нужно эта функциональность. Надеюсь, кто-то еще найдет это полезным.

Просмотреть ветку на GitHub.

person Batkins    schedule 01.02.2013