开发者社区> 问答> 正文

ruby sdk支持流式上传吗

已解决

展开
收起
2018-01-01 20:33:17 898 0
1 条回答
写回答
取消 提交回答
  • 采纳回答

    详细解答可以参考官方帮助文档

    上传文件(Object)

    OSS Ruby SDK提供了丰富的文件上传接口,用户可以通过以下方式向OSS中上传文件:

    • 上传本地文件到OSS
    • 流式上传
    • 断点续传上传
    • 追加上传
    • 上传回调

    上传本地文件

    通过Bucket#put_object接口,并指定:file参数来上传一个本地文件到OSS:

    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. bucket.put_object('my-object', :file => 'local-file')

    流式上传

    在进行大文件上传时,往往不希望一次性处理全部的内容然后上传,而是希望流式地处理,一次上传一部分内容。甚至如果要上传的内容本身就来自网络,不能一次获取,那只能流式地上传。通过Bucket#put_object接口,并指定block参数来将流式生成的内容上传到OSS:

    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. bucket.put_object('my-object') do |stream|
    7. 100.times { |i| stream << i.to_s }
    8. end

    断点续传上传

    当上传大文件时,如果网络不稳定或者程序崩溃了,则整个上传就失败了。用户不得不重头再来,这样做不仅浪费资源,在网络不稳定的情况下,往往重试多次还是无法完成上传。通过Bucket#resumable_upload接口来实现断点续传上传。它有以下参数:

    • key 上传到OSS的Object名字
    • file 待上传的本地文件路径
    • opts 可选项,主要包括:
      • :cpt_file 指定checkpoint文件的路径,如果不指定则默认为与本地文件同目录下的file.cpt,其中file是本地文件的名字
      • :disable_cpt 如果指定为true,则上传过程中不会记录上传进度,失败后也无法进行续传
      • :part_size 指定每个分片的大小,默认为4MB
      • &block 如果调用时候传递了block,则上传进度会交由block处理

    详细的参数请参考API文档

    其实现的原理是将要上传的文件分成若干个分片分别上传,最后所有分片都上传成功后,完成整个文件的上传。在上传的过程中会记录当前上传的进度信息(记录在checkpoint文件中),如果上传过程中某一分片上传失败,再次上传时会从checkpoint文件中记录的点继续上传。这要求再次调用时要指定与上次相同的checkpoint文件。上传完成后,checkpoint文件会被删除。

    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. bucket.resumable_upload('my-object', 'local-file') do |p|
    7. puts "Progress: #{p}"
    8. end
    9. bucket.resumable_upload(
    10. 'my-object', 'local-file',
    11. :part_size => 100 * 1024, :cpt_file => '/tmp/x.cpt') { |p|
    12. puts "Progress: #{p}"
    13. }

    注意:

    • SDK会将上传的中间状态信息记录在cpt文件中,所以要确保用户对cpt文件有写权限。
    • cpt文件记录了上传的中间状态信息并自带了校验,用户不能去编辑它,如果cpt文件损坏则上传无法继续。整个上传完成后cpt文件会被删除。
    • 如果上传过程中本地文件发生了改变,则上传会失败。

    追加上传

    OSS支持可追加的文件类型,通过Bucket#append_object来上传可追加的文件,调用时需要指定文件追加的位置,对于新创建文件,这个位置是0;对于已经存在的文件,这个位置必须是追加前文件的长度。

    • 文件不存在时,调用append_object会创建一个可追加的文件
    • 文件存在时,调用append_object会向文件末尾追加内容
    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. # 创建可追加的文件
    7. bucket.append_object('my-object', 0) {}
    8. # 向文件末尾追加内容
    9. next_pos = bucket.append_object('my-object', 0) do |stream|
    10. 100.times { |i| stream << i.to_s }
    11. end
    12. next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-1')
    13. next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-2')

    注意:

    • 只能向可追加的文件(即通过 append_object 创建的文件)追加内容。
    • 可追加的文件不能被拷贝。

    上传回调

    用户在上传文件时可以指定“上传回调”,这样在文件上传成功后OSS会向用户提供的服务器地址发起一个HTTP POST请求,相当于一个通知机制。用户可以在收到回调的时候做相应的动作。更多有关上传回调的内容请参考OSS 上传回调

    目前OSS支持上传回调的接口只有put_objectresumable_upload

    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. callback = Aliyun::OSS::Callback.new(
    7. url: 'http://10.101.168.94:1234/callback',
    8. query: {user: 'put_object'},
    9. body: 'bucket=${bucket}&object=${object}'
    10. )
    11. begin
    12. bucket.put_object('files/hello', file: '/tmp/x', callback: callback)
    13. rescue Aliyun::OSS::CallbackError => e
    14. puts "Callback failed: #{e.message}"
    15. end

    上面的例子使用put_object上传了一个文件,并指定了上传回调并将此次上传的bucket和object信息添加在body中,应用服务器收到这个回调后,就知道这个文件已经成功上传到OSS了。

    resumable_upload的使用方法类似:

    1. require 'aliyun/oss'
    2. client = Aliyun::OSS::Client.new(
    3. endpoint: 'endpoint',
    4. access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')
    5. bucket = client.get_bucket('my-bucket')
    6. callback = Aliyun::OSS::Callback.new(
    7. url: 'http://10.101.168.94:1234/callback',
    8. query: {user: 'put_object'},
    9. body: 'bucket=${bucket}&object=${object}'
    10. )
    11. begin
    12. bucket.resumable_upload('files/hello', '/tmp/x', callback: callback)
    13. rescue Aliyun::OSS::CallbackError => e
    14. puts "Callback failed: #{e.message}"
    15. end

    注意:

    • callback的URL不能包含query string,而应该在:query参数中指定。
    • 可能出现文件上传成功,但是执行回调失败的情况,此时client会抛出 CallbackError,用户如果要忽略此错误,需要显式接住这个异常。
    • 详细的例子请参考callback.rb
    • 接受回调的server请参考callback_server.rb
    2018-01-08 17:34:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
从 SDK 到编解码:视频直播架构解析 立即下载
跨平台的云服务SDK需要什么 立即下载
一个跨平台的云服务SDK需要什么 立即下载