在OSS中,操作的基本数据单元是文件(Object)。OSS Ruby SDK提供了丰富的文件上传方式。
上传本地文件
通过Bucket#put_object
接口,并指定:file
参数来上传一个本地文件到OSS。
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') bucket.put_object('my-object', :file => 'local-file')
流式上传
如果要上传的文件太大,或者一次性上传耗时太长,您可以通过流式上传的方式,一次处理部分内容,直到完成整个文件的上传。
通过Bucket#put_object
接口,并指定block
参数将流式生成的内容上传到OSS:
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') bucket.put_object('my-object') do |stream| 100.times { |i| stream << i.to_s } end
断点续传上传
断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。
通过Bucket#resumable_upload
接口实现断点续传上传,包含以下参数:
- key上传到OSS的Object名字。
- file待上传的本地文件路径。
- opts可选项,主要包括:
- :cpt_file指定checkpoint文件的路径。如果不指定,则默认是本地文件同目录下的
file.cpt
,其中file
是本地文件的名字。 - :disable_cpt如果指定为true,则上传过程中不会记录上传进度,上传失败后也无法进行续传。
- :part_size指定每个分片的大小,默认为4MB。
- &block如果调用时传递了block,则上传进度会由block来处理。
- :cpt_file指定checkpoint文件的路径。如果不指定,则默认是本地文件同目录下的
详细的参数说明请参考
API文档。
说明 如果上传过程中某一分片上传失败,再次上传时会从 checkpoint文件中记录的点继续上传。再次调用
Bucket#resumable_upload
时需指定与上次相同的checkpoint文件。文件上传完成后,checkpoint文件将被删除。
以下代码用于断点续传上传:
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') bucket.resumable_upload('my-object', 'local-file') do |p| puts "Progress: #{p}" end bucket.resumable_upload( 'my-object', 'local-file', :part_size => 100 * 1024, :cpt_file => '/tmp/x.cpt') { |p| puts "Progress: #{p}" }
说明
- SDK会将上传的中间状态信息记录在cpt文件中,用户需确保对cpt文件有写权限。
- cpt文件不仅记录了上传的中间状态信息,还附带校验功能。cpt文件不允许编辑。如果cpt文件损坏则无法继续上传,整个文件上传完成后cpt文件会被删除。
- 上传过程中如果本地文件发生了改变,会导致上传失败。
追加上传
通过Bucket#append_object
来上传可追加的文件。调用该接口时需要指定文件追加的position,首次追加操作的position必须为0,后续追加操作的position是Object的当前大小。
- 文件不存在时,调用
append_object
会创建一个可追加的文件。 - 文件存在时,调用
append_object
会向文件末尾追加内容。
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') # 创建可追加的文件 bucket.append_object('my-object', 0) {} # 向文件末尾追加内容 next_pos = bucket.append_object('my-object', 0) do |stream| 100.times { |i| stream << i.to_s } end next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-1') next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-2')
说明
- 只能向Appendable类型的Object追加内容。
- 不支持对Appendable类型的Object进行拷贝。
上传回调
用户在上传文件时可以指定上传回调。文件上传成功后,OSS会向用户提供的服务器地址发起HTTP POST请求,用户可以在收到回调时执行相应的操作。更多有关上传回调的内容,请参考
OSS 上传回调。
使用put_object
上传文件时指定了上传回调,并将此次上传的Bucket和Object信息添加在body中。如果应用服务器收到这个回调,则表明文件已成功上传到OSS了。
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') callback = Aliyun::OSS::Callback.new( url: 'http://10.101.168.94:1234/callback', query: {user: 'put_object'}, body: 'bucket=${bucket}&object=${object}' ) begin bucket.put_object('files/hello', file: '/tmp/x', callback: callback) rescue Aliyun::OSS::CallbackError => e puts "Callback failed: #{e.message}" end
resumable_upload
的调用方法与put_object
类似。
require 'aliyun/oss' client = Aliyun::OSS::Client.new( endpoint: 'endpoint', access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret') bucket = client.get_bucket('my-bucket') callback = Aliyun::OSS::Callback.new( url: 'http://10.101.168.94:1234/callback', query: {user: 'put_object'}, body: 'bucket=${bucket}&object=${object}' ) begin bucket.resumable_upload('files/hello', '/tmp/x', callback: callback) rescue Aliyun::OSS::CallbackError => e puts "Callback failed: #{e.message}" end
说明
- callback的URL不能包含query string,须在
:query
参数中指定。 - 如果出现文件上传成功,但是执行回调失败时,client会抛出
CallbackError
。用户如果忽略此错误,需要显式接住这个异常。 - 接收回调的server请参见callback_server.rb。