human: 如何处理七牛云的对象存储AWS SDK for Ruby

gpt: [对象存储](https://developer.qiniu.com/kodo) > 使用指南 >
[开发指南](https://developer.qiniu.com/kodo/development_guidelines/8596/development-
guidelines) > [AWS S3
兼容](https://developer.qiniu.com/kodo/development_guidelines/4086/aws-s3-compatible)
> [兼容 SDK 示例](https://developer.qiniu.com/kodo/development_guidelines/12553/S3
SDK sample) > AWS SDK for Ruby

#  AWS SDK for Ruby

最近更新时间: 2024-02-19 17:03:42

# 导入 AWS SDK for Ruby

确保 Ruby v2.3 或更新版本已经安装。

初始化 `bundler` 项目

    
    
    bundle init
    

添加 AWS SDK for Ruby 包

    
    
    bundle add aws-sdk-s3 --version "=1.136.0"
    bundle add aws-sdk-sts --version "=1.11.0"
    bundle add nokogiri --version "=1.15.4"
    

对于之后的每个代码示例，将代码创建在 `main.rb` 后，执行

    
    
    ruby main.rb
    

即可执行代码。

# 对象上传

## 获取客户端上传 URL

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    puts s3.bucket('<Bucket>').object('<Key>').presigned_url(:put)
    

这段代码将生成一个经过预先签名的客户端上传 URL，有效期为 900 秒，客户端可以在过期时间内对该 URL 发送 HTTP PUT 请求将文件上传。

以下是用 curl 上传文件的案例：

    
    
    curl -X PUT --upload-file "<path/to/file>" "<presigned url>"
    

您也可以自行指定上传凭证的有效期，例如：

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    puts s3.bucket('<Bucket>').object('<Key>').presigned_url(:put, expires_in: 3600)
    

## 服务器端直传

### 单请求上传（文件）

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    open('<path/to/upload>', 'rb') do |file|
        resp = s3.put_object(bucket: '<Bucket>', key: '<Key>', body: file)
        puts resp[:etag]
    end
    

### 单请求上传（数据流）

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    resp = s3.put_object(bucket: '<Bucket>', key: '<Key>', body: 'Hello from Qiniu S3!')
    puts resp[:etag]
    

### 分片上传（文件）

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    create_multipart_upload_resp = s3.create_multipart_upload(bucket: '<Bucket>', key: '<Key>')
    
    PART_SIZE = 5 * 1024 * 1024 # 分片大小为 5 MB
    parts = []
    open('<path/to/upload>', 'rb') do |file|
        # 这里给出的案例是串行分片上传。可以自行改造成并行分片上传以进一步提升上传速度
        (1..).each do |part_number|
            part_body = file.read(PART_SIZE)
            break if part_body.nil?
            upload_part_response = s3.upload_part(
                bucket: create_multipart_upload_resp[:bucket],
                key: create_multipart_upload_resp[:key],
                upload_id: create_multipart_upload_resp[:upload_id],
                part_number: part_number,
                body: part_body,
            )
            parts << {etag: upload_part_response[:etag], part_number: part_number}
        end
    end
    
    complete_multipart_upload_response = s3.complete_multipart_upload(
        bucket: create_multipart_upload_resp[:bucket],
        key: create_multipart_upload_resp[:key],
        upload_id: create_multipart_upload_resp[:upload_id],
        multipart_upload: {parts: parts},
    )
    puts complete_multipart_upload_response[:etag]
    

### 上传文件

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.bucket('<Bucket>').object('<Key>').upload_file('<path/to/upload>')
    puts 'Done'
    

# 对象下载

## 获取客户端下载 URL

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    puts s3.bucket('<Bucket>').object('<Key>').presigned_url(:get)
    

这段代码将生成一个经过预先签名的客户端下载 URL，有效期为 900 秒，客户端可以在过期时间内对该 URL 发送 HTTP GET 请求将文件下载。

以下是用 curl 下载文件的案例：

    
    
    curl -o "<path/to/download>" "<presigned url>"
    

您也可以自行指定下载凭证的有效期，例如：

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    puts s3.bucket('<Bucket>').object('<Key>').presigned_url(:get, expires_in: 3600)
    

## 服务器端直接下载

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    response = s3.get_object(bucket: '<Bucket>', key: '<Key>')
    puts response[:etag]
    

## 下载文件

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.bucket('<Bucket>').object('<Key>').get(response_target: '<path/to/download>')
    puts 'Done'
    

# 对象管理

## 获取对象信息

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    response = s3.get_object(bucket: '<Bucket>', key: '<Key>')
    puts response[:etag]
    

## 修改对象 MimeType

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.copy_object(bucket: '<Bucket>', key: '<Key>', copy_source: '/<Bucket>/<Key>', metadata_directive: 'REPLACE', content_type: '<NewContentType>')
    puts 'Done'
    

## 修改对象存储类型

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.copy_object(bucket: '<Bucket>', key: '<Key>', copy_source: '/<Bucket>/<Key>', metadata_directive: 'REPLACE', storage_class: 'GLACIER')
    puts 'Done'
    

## 复制对象副本

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.copy_object(bucket: '<ToBucket>', key: '<ToKey>', copy_source: '/<FromBucket>/<FromKey>', metadata_directive: 'COPY')
    puts 'Done'
    

## 复制对象副本（大于 5GB）

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    head_object_resp = s3.head_object(bucket: '<FromBucket>', key: '<FromKey>')
    create_multipart_upload_resp = s3.create_multipart_upload(bucket: '<ToBucket>', key: '<ToKey>')
    
    PART_SIZE = 5 * 1024 * 1024 # 分片大小为 5 MB
    copied = 0
    parts = []
    # 这里给出的案例是串行分片复制。可以自行改造成并行分片复制以进一步提升复制速度
    (1..).each do |part_number|
        break if head_object_resp[:content_length] <= copied
        part_size = [PART_SIZE, head_object_resp[:content_length] - copied].min
        upload_part_copy_response = s3.upload_part_copy(
            bucket: create_multipart_upload_resp[:bucket],
            key: create_multipart_upload_resp[:key],
            upload_id: create_multipart_upload_resp[:upload_id],
            part_number: part_number,
            copy_source: "/<FromBucket>/<FromKey>",
            copy_source_range: "bytes=#{copied}-#{copied+part_size-1}",
        )
        parts << {etag: upload_part_copy_response[:copy_part_result][:etag], part_number: part_number}
        copied += part_size
    end
    
    complete_multipart_upload_response = s3.complete_multipart_upload(
        bucket: create_multipart_upload_resp[:bucket],
        key: create_multipart_upload_resp[:key],
        upload_id: create_multipart_upload_resp[:upload_id],
        multipart_upload: {parts: parts},
    )
    puts complete_multipart_upload_response[:etag]
    

## 删除空间中的文件

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.delete_object(bucket: '<Bucket>', key: '<Key>')
    puts 'Done'
    

## 获取指定前缀的文件列表

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    resp = s3.list_objects_v2(bucket: '<Bucket>', prefix: '<KeyPrefix>')
    resp[:contents].each do |object|
        puts "Key: #{object[:key]}"
        puts "ETag: #{object[:etag]}"
    end
    

## 批量删除空间中的文件

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    
    s3 = Aws::S3::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    
    s3.delete_objects(bucket: '<Bucket>', delete: { objects: [{key: '<Key1>'}, {key: '<Key2>'}, {key: '<Key3>'}] })
    puts 'Done'
    

# 临时安全凭证

创建 `main.rb`

    
    
    require 'aws-sdk-s3'
    require 'aws-sdk-sts'
    
    sts = Aws::STS::Client::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new('<QiniuAccessKey>', '<QiniuSecretKey>'),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    get_federation_token_response = sts.get_federation_token({
        name: 'Bob',
        duration_seconds: 3600,
        policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":["*"],"Resource":["*"]}]}'
    })
    
    s3 = Aws::S3::Resource::new(
        region: 'cn-east-1', # 华东-浙江区 region id
        credentials: Aws::Credentials.new(
            get_federation_token_response.credentials.access_key_id,
            get_federation_token_response.credentials.secret_access_key,
            get_federation_token_response.credentials.session_token
        ),
        endpoint: 'https://s3.cn-east-1.qiniucs.com', # 华东-浙江区 endpoint
    )
    # 可以使用这些临时凭证调用 S3 服务
    s3.buckets.each {|bucket| puts bucket.name}
    

以上内容是否对您有帮助？