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

上傳檔案

更新時間: Oct 19, 2018

在OSS中,操作的基本資料單元是檔案(Object)。OSS Python SDK提供了豐富的檔案上傳方式:

  • 簡單上傳:檔案最大不能超過5GB。
  • 追加上傳:檔案最大不能超過5GB。
  • 斷點續傳上傳:支援並發、斷點續傳、自訂分區大小。大檔案上傳推薦使用斷點續傳。最大不能超過48.8TB。
  • 分區上傳:當檔案較大時,可以使用分區上傳,最大不能超過48.8TB。

說明:各種上傳方式的適用場景請參見開發指南中的上傳檔案。

上傳過程中,您還可以通過上傳進度條功能查看上傳進度。上傳完成後,您還可以進行上傳回調

簡單上傳

通過bucket.put_object方法上傳檔案。上傳方法支援多種類型的輸入源,輸入源有如下幾種類型:

類型 上傳方式
字元串 直接上傳
Bytes 直接上傳
Unicode 自動轉換為UTF-8編碼的Bytes進行上傳
本地檔案 檔案對象(File Object),必須以二進位方式開啟(如“rb”模式)
網路流 可迭代對象(Iterable),以Chunked Encoding的方式上傳

上傳字元串

以下代碼用於上傳字元串:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. # 傳回值。
  8. result = bucket.put_object('<yourObjectName>', 'content of object')
  9. # HTTP返回碼。
  10. print('http status: {0}'.format(result.status))
  11. # 請求ID。請求ID是請求的唯一標識,強烈建議在程式日誌中添加此參數。
  12. print('request_id: {0}'.format(result.request_id))
  13. # ETag是put_object方法傳回值特有的屬性。
  14. print('ETag: {0}'.format(result.etag))
  15. # HTTP回應標頭部。
  16. print('date: {0}'.format(result.headers['date']))

上傳Bytes

以下代碼用於上傳Bytes:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. bucket.put_object('<yourObjectName>', b'content of object')

上傳Unicode

以下代碼用於上傳Unicode:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. bucket.put_object('<yourObjectName>', u'content of object')

上傳本地檔案

以下代碼用於上傳本地檔案:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. # 必須以二進位的方式開啟檔案,因為需要知道檔案包含的位元組數。
  8. with open('<yourLocalFile>', 'rb') as fileobj:
  9. # Seek方法用於指定從第1000個位元組位置開始讀寫。上傳時會從您指定的第1000個位元組位置開始上傳,直到檔案結束。
  10. fileobj.seek(1000, os.SEEK_SET)
  11. # Tell方法用於返回當前位置。
  12. current = fileobj.tell()
  13. bucket.put_object('<yourObjectName>', fileobj)

Python SDK還提供了一個更加便捷的方法用於上傳本地檔案:

  1. bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>')

上傳網路流

以下代碼用於上傳網路流:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. import requests
  4. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  5. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  6. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  7. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  8. # requests.get返回的是一個可迭代對象(Iterable),此時Python SDK會通過Chunked Encoding方式上傳。
  9. input = requests.get('http://www.aliyun.com')
  10. bucket.put_object('<yourObjectName>', input)

追加上傳

以下代碼用於追加上傳檔案:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. # 設定首次上傳的追加位置(Position參數)為0。
  8. result = bucket.append_object('<yourObjectName>', 0, 'content of first append')
  9. # 如果不是首次上傳,可以通過bucket.head_object方法或上次追加傳回值的next_position屬性,得到追加位置。
  10. bucket.append_object('<yourObjectName>', result.next_position, 'content of second append')

如果檔案已經存在,如下兩種情況將會拋出異常:

  • 不是可追加檔案,則拋出ObjectNotAppendable異常。
  • 是可追加檔案,但設定的追加位置和檔案當前長度不等,則拋出PositionNotEqualToLength異常。

斷點續傳上傳

斷點續傳上傳將要上傳的檔案分成若干個分區(Part)分別上傳,所有分區都上傳完成後,將所有分區合并成完整的檔案,完成整個檔案的上傳。

您可以通過oss2.resumable_upload方法斷點續傳上傳指定檔案,該方法包含以下參數:

參數 描述 是否必需 預設值
bucket 儲存空間名稱
key 檔案名稱
filename 待上傳的本地檔案名稱
store 指定保存斷點資訊的目錄 HOME目錄下建立的.py-oss-upload目錄
headers HTTP頭部
multipart_threshold 檔案長度大於該值時,則用分區上傳 10MB
part_size 分區大小 自動計算
progress_callback 上傳進度回呼函數
num_threads 並發上傳的線程數 1

以下代碼用於斷點續傳上傳:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  4. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  5. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  6. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  7. # 當檔案長度大於或等於選擇性參數multipart_threshold(預設值為10MB)時,會使用分區上傳。如未使用參數store指定目錄,則會在HOME目錄下建立.py-oss-upload目錄來保存斷點資訊。
  8. oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>')

Python SDK 2.1.0以上版本支援設定選擇性參數進行斷點續傳上傳,代碼如下:

  1. # 如使用store指定了目錄,則保存斷點資訊在指定目錄中。如使用num_threads設定上傳並發數,請將oss2.defaults.connection_pool_size設成大於或等於線程數。預設線程數為1。
  2. oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>',
  3. store=oss2.ResumableStore(root='/tmp'),
  4. multipart_threshold=100*1024,
  5. part_size=100*1024,
  6. num_threads=4)

斷點續傳詳情請參見開發指南中的斷點續傳

分區上傳

分區上傳(Multipart Upload)分為以下三個步驟:

  • 初始化(bucket.init_multipart_upload):獲得Upload ID。
  • 上傳分區(bucket.upload_part):上傳分區資料。這一步可以並發進行。
  • 完成上傳(bucket.complete_multipart_upload):所有分區上傳完成後,合并分區,生成OSS檔案。

以下代碼用於分區上傳檔案:

  1. # -*- coding: utf-8 -*-
  2. import os
  3. from oss2 import SizedFileAdapter, determine_part_size
  4. from oss2.models import PartInfo
  5. import oss2
  6. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  7. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  8. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  9. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  10. key = '<yourObjectName>'
  11. filename = '<yourLocalFile>'
  12. total_size = os.path.getsize(filename)
  13. # determine_part_size方法用來確定分區大小。
  14. part_size = determine_part_size(total_size, preferred_size=100 * 1024)
  15. # 初始化分區。
  16. upload_id = bucket.init_multipart_upload(key).upload_id
  17. parts = []
  18. # 逐個上傳分區。
  19. with open(filename, 'rb') as fileobj:
  20. part_number = 1
  21. offset = 0
  22. while offset < total_size:
  23. num_to_upload = min(part_size, total_size - offset)
  24. # SizedFileAdapter(fileobj, size)方法會生成一個新的檔案對象,重新計算起始追加位置。
  25. result = bucket.upload_part(key, upload_id, part_number,
  26. SizedFileAdapter(fileobj, num_to_upload))
  27. parts.append(PartInfo(part_number, result.etag))
  28. offset += num_to_upload
  29. part_number += 1
  30. # 完成分區上傳。
  31. bucket.complete_multipart_upload(key, upload_id, parts)
  32. # 驗證分區上傳。
  33. with open(filename, 'rb') as fileobj:
  34. assert bucket.get_object(key).read() == fileobj.read()

上傳進度條

進度條用於指示上傳或下載的進度。下面的代碼以bucket.put_object方法為例,介紹如何使用進度條。

  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. import os, sys
  4. import oss2
  5. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  6. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  7. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  8. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  9. # 當無法確定待上傳的資料長度時,total_bytes的值為None。
  10. def percentage(consumed_bytes, total_bytes):
  11. if total_bytes:
  12. rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
  13. print('\r{0}% '.format(rate), end='')
  14. sys.stdout.flush()
  15. # progress_callback為選擇性參數,用於實現進度條功能。
  16. bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage)

進度條的完整範例程式碼請參見GitHub

上傳回調

以下代碼用於上傳回調:

  1. # -*- coding: utf-8 -*-
  2. import json
  3. import base64
  4. import os
  5. import oss2
  6. # 阿里雲主帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM帳號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM帳號。
  7. auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
  8. # Endpoint以杭州為例,其它Region請按實際情況填寫。
  9. bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
  10. # 準備回調參數。
  11. callback_dict = {}
  12. # 設定回調請求的伺服器位址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。
  13. callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'
  14. # 設定回調請求消息頭中Host的值, 如oss-cn-hangzhou.aliyuncs.com。
  15. callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'
  16. # 設定發起回調時請求body的值。
  17. callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'
  18. # 設定發起回調請求的Content-Type。
  19. callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'
  20. # 回調參數是Json格式,並且需要Base64編碼。
  21. callback_param = json.dumps(callback_dict).strip()
  22. base64_callback_body = base64.b64encode(callback_param)
  23. # 回調參數編碼後放在Header中發送給OSS。
  24. headers = {'x-oss-callback': base64_callback_body}
  25. # 上傳並回調。
  26. result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers)

put_object、put_object_from_file、complete_multipart_upload支援上傳回調功能。上傳回調的詳細說明請參見API參考中的上傳回調。上傳回調的完整範例程式碼請參見GitHub