本文針對大文件的傳輸場景,介紹如何使用Go SDK V2新增的上傳管理器Uploader模塊進行大文件上傳。
注意事項
本文示例代碼以華東1(杭州)的地域ID
cn-hangzhou
為例,默認使用外網Endpoint,如果您希望通過與OSS同地域的其他阿里云產品訪問OSS,請使用內網Endpoint。關于OSS支持的Region與Endpoint的對應關系,請參見OSS地域和訪問域名。本文以從環境變量讀取訪問憑證為例。如何配置訪問憑證,請參見配置訪問憑證。
要進行大文件上傳,您必須有
oss:PutObject
權限。具體操作,請參見為RAM用戶授權自定義的權限策略。
方法定義
上傳管理器功能簡介
Go SDK V2新增上傳管理器Uploader提供了通用的上傳接口,隱藏了底層接口的實現細節,提供便捷的大文件上傳能力。
上傳管理器Uploader底層利用分片上傳接口,把大文件或者流分成多個較小的分片并發上傳,提升上傳的性能。
上傳管理器Uploader同時提供了斷點續傳的能力,即在上傳過程中,記錄已完成的分片狀態,如果出現網絡中斷、程序異常退出等問題導致文件上傳失敗,甚至重試多次仍無法完成上傳,再次上傳時,可以通過斷點記錄文件恢復上傳。
上傳管理器Uploader的常用方法如下:
type Uploader struct {
...
}
// 用于創建新的上傳管理器
func (c *Client) NewUploader(optFns ...func(*UploaderOptions)) *Uploader
// 用于上傳文件流
func (u *Uploader) UploadFrom(ctx context.Context, request *PutObjectRequest, body io.Reader, optFns ...func(*UploaderOptions)) (*UploadResult, error)
// 用于上傳本地大文件
func (u *Uploader) UploadFile(ctx context.Context, request *PutObjectRequest, filePath string, optFns ...func(*UploaderOptions)) (*UploadResult, error)
請求參數列表
參數名 | 類型 | 說明 |
ctx | context.Context | 請求的上下文 |
request | *PutObjectRequest | 上傳對象的請求參數,和 PutObject 接口的請求參數一致,具體請參見PutObjectRequest |
body | io.Reader | 需要上傳的流
|
filePath | string | 本地文件路徑 |
optFns | ...func(*UploaderOptions) | (可選)配置選項 |
其中,UploaderOptions常用參數說明列舉如下:
參數名 | 類型 | 說明 |
PartSize | int64 | 指定分片大小,默認值為 6MiB |
ParallelNum | int | 指定上傳任務的并發數,默認值為 3。針對的是單次調用的并發限制,而不是全局的并發限制 |
LeavePartsOnError | bool | 當上傳失敗時,是否保留已上傳的分片,默認不保留 |
EnableCheckpoint | bool | 是否開啟斷點上傳功能,默認不開啟 說明 EnableCheckpoint參數目前僅對UploadFile 接口有效,UploadFrom接口暫不支持 |
CheckpointDir | string | 指定記錄文件的保存路徑,例如 /local/dir/, 當EnableCheckpoint 為 true時有效 |
當使用NewUploader實例化實例時,您可以指定多個配置選項來自定義對象的上傳行為。也可以在每次調用上傳接口時,指定多個配置選項來自定義每次上傳對象的行為。
設置Uploader的配置參數
u := client.NewUploader(func(uo *oss.UploaderOptions) { uo.PartSize = 10 * 1024 * 1024 })
設置每次上傳請求的配置參數
request := &oss.PutObjectRequest{Bucket: oss.Ptr("bucket"), Key: oss.Ptr("key")} result, err := u.UploadFile(context.TODO(), request, "/local/dir/example", func(uo *oss.UploaderOptions) { uo.PartSize = 10 * 1024 * 1024 })
示例代碼
您可以通過以下代碼使用上傳管理器上傳本地大文件到存儲空間。
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定義全局變量
var (
region string // 存儲區域
bucketName string // 存儲空間名稱
objectName string // 對象名稱
)
// init函數用于初始化命令行參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the source object.")
}
func main() {
// 解析命令行參數
flag.Parse()
// 檢查bucket名稱是否為空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 檢查region是否為空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 檢查object名稱是否為空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
// 加載默認配置并設置憑證提供者和區域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 創建OSS客戶端
client := oss.NewClient(cfg)
// 創建上傳管理器
u := client.NewUploader()
// 定義本地文件路徑,需要替換為您的實際本地文件路徑
localFile := "yourLocalFile"
// 執行上傳大文件的操作
result, err := u.UploadFile(context.TODO(),
&oss.PutObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName)},
localFile)
if err != nil {
log.Fatalf("failed to upload file %v", err)
}
// 打印上傳文件的結果
log.Printf("upload file result:%#v\n", result)
}
常見使用場景
使用上傳管理器啟動斷點續傳功能
您可以使用以下代碼設置上傳管理器Uploader的配置參數,啟動斷點續傳功能。
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定義全局變量
var (
region string // 存儲區域
bucketName string // 存儲空間名稱
objectName string // 對象名稱
)
// init函數用于初始化命令行參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the source object.")
}
func main() {
// 解析命令行參數
flag.Parse()
// 檢查bucket名稱是否為空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 檢查region是否為空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 檢查object名稱是否為空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
// 加載默認配置并設置憑證提供者和區域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 創建OSS客戶端
client := oss.NewClient(cfg)
// 創建上傳器,并啟用斷點續傳功能
u := client.NewUploader(func(uo *oss.UploaderOptions) {
uo.CheckpointDir = "./checkpoint" // 指定記錄文件的保存路徑
uo.EnableCheckpoint = true // 開啟斷點續傳
})
// 定義本地文件路徑,需要替換為您的實際本地文件路徑
localFile := "yourLocalFile"
// 執行上傳大文件的操作
result, err := u.UploadFile(context.TODO(),
&oss.PutObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName)},
localFile)
if err != nil {
log.Fatalf("failed to upload file %v", err)
}
// 打印上傳文件的結果
log.Printf("upload file result:%#v\n", result)
}
使用上傳管理器上傳本地文件流
您可以通過以下代碼使用上傳管理器上傳本地文件流。
package main
import (
"context"
"flag"
"io"
"log"
"os"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定義全局變量
var (
region string // 存儲區域
bucketName string // 存儲空間名稱
objectName string // 對象名稱
)
// init函數用于初始化命令行參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
// 解析命令行參數
flag.Parse()
// 檢查bucket名稱是否為空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 檢查region是否為空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 檢查object名稱是否為空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, object name required")
}
// 加載默認配置并設置憑證提供者和區域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 創建OSS客戶端
client := oss.NewClient(cfg)
// 創建上傳器
u := client.NewUploader()
// 將“yourLocalFile”替換為實際的文件路徑和文件名稱,打開本地文件并創建io.Reader實例
file, err := os.Open("yourLocalFile")
if err != nil {
log.Fatalf("failed to open local file %v", err)
}
defer file.Close()
var r io.Reader = file
// 執行上傳文件流的操作
result, err := u.UploadFrom(context.TODO(),
&oss.PutObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName),
},
r, // 上傳文件流
)
if err != nil {
log.Fatalf("failed to upload file stream %v", err)
}
// 打印上傳文件流的結果
log.Printf("upload file stream, etag: %v\n", oss.ToString(result.ETag))
}
使用上傳管理器設置分片大小和并發數
您可以使用以下代碼設置上傳管理器Uploader的配置參數,設置分片大小和并發數。
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定義全局變量
var (
region string // 存儲區域
bucketName string // 存儲空間名稱
objectName string // 對象名稱
)
// init函數用于初始化命令行參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the source object.")
}
func main() {
// 解析命令行參數
flag.Parse()
// 檢查bucket名稱是否為空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 檢查region是否為空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 檢查object名稱是否為空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
// 加載默認配置并設置憑證提供者和區域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 創建OSS客戶端
client := oss.NewClient(cfg)
// 創建上傳器
u := client.NewUploader(func(uo *oss.UploaderOptions) {
uo.PartSize = 1024 * 1024 * 5 // 設置分片大小為5MB
uo.ParallelNum = 5 // 設置并行上傳數為5
})
// 定義本地文件路徑,需要替換為您的實際本地文件路徑
localFile := "yourLocalFile"
// 執行上傳大文件的操作
result, err := u.UploadFile(context.TODO(),
&oss.PutObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName)},
localFile)
if err != nil {
log.Fatalf("failed to upload file %v", err)
}
// 打印上傳文件的結果
log.Printf("upload file result:%#v\n", result)
}
相關文檔
關于上傳管理器的更多信息,請參見開發者指南。
關于大文件上傳的API接口,請參見UploadFrom和UploadFile。