阿里雲團隊努力不懈,力求將最新的技術內容更快地以您最熟悉的語言呈現。本文由簡體中文內容自動轉碼而成,過程無人工干預。阿里雲不保證此自動轉碼的準確性、完整性及時效性。因轉碼造成的任何內容錯誤及因此可能帶來的損失,阿里雲概不負責,敬請見諒。本文内容請以簡體中文版本為準。
全部產品
Search
文件中心

上傳檔案

更新時間: Oct 30, 2018

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