全部產品
Search
文件中心

Object Storage Service:檔案上傳管理器(Go SDK V2)

更新時間:Aug 02, 2025

本文針對檔案的傳輸情境,介紹如何使用Go SDK V2新增的上傳管理器Uploader模組進行檔案上傳。

注意事項

  • 本文範例程式碼以華東1(杭州)的地區IDcn-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

需要上傳的流

  • 當 body 只支援io.Reader類型,必須先把資料緩衝在記憶體中,然後才能上傳該部分

  • 當 body 同時支援 io.Reader, io.Seeker 和 io.ReaderAt 類型時,不需要把資料緩衝在記憶體裡

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(&region, "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 := "/Users/yourLocalPath/yourFileName"

	// 執行上傳檔案的操作
	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(&region, "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 = "/Users/yourLocalPath/checkpoint/" // 指定斷點記錄檔案的儲存路徑
		uo.EnableCheckpoint = true        // 開啟斷點續傳
	})

	// 定義本地檔案路徑,需要替換為您的實際本地檔案路徑和檔案名稱
	localFile := "/Users/yourLocalPath/yourFileName"

	// 執行上傳檔案的操作
	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(&region, "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()

	// 將“/Users/yourLocalPath/yourFileName”替換為實際的檔案路徑和檔案名稱,開啟本地檔案並建立io.Reader執行個體
	file, err := os.Open("/Users/yourLocalPath/yourFileName")
	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(&region, "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 := "/Users/yourLocalPath/yourFileName"

	// 執行上傳檔案的操作
	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"
	"encoding/base64"
	"encoding/json"
	"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(&region, "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 := "/Users/yourLocalPath/yourFileName"

	// 定義回調參數
	callbackMap := map[string]string{
		"callbackUrl":      "https://example.com:23450/callback",                                                        // 設定回調伺服器的URL,例如https://example.com:23450。
		"callbackBody":     "bucket=${bucket}&object=${object}&size=${size}&my_var_1=${x:my_var1}&my_var_2=${x:my_var2}", // 設定回調請求體。
		"callbackBodyType": "application/x-www-form-urlencoded",                                                          //設定回調請求體類型。
	}

	// 將回調參數轉換為JSON並進行Base64編碼,以便將其作為回調參數傳遞
	callbackStr, err := json.Marshal(callbackMap)
	if err != nil {
		log.Fatalf("failed to marshal callback map: %v", err)
	}
	callbackBase64 := base64.StdEncoding.EncodeToString(callbackStr)

	// 定義自訂回調參數
	callbackVarMap := map[string]string{}
	callbackVarMap["x:my_var1"] = "thi is var 1"
	callbackVarMap["x:my_var2"] = "thi is var 2"

	// 將回調參數轉換為JSON並進行Base64編碼,以便將其作為回調參數傳遞
	callbackVarStr, err := json.Marshal(callbackVarMap)
	if err != nil {
		log.Fatalf("failed to marshal callback var: %v", err)
	}
	callbackVarBase64 := base64.StdEncoding.EncodeToString(callbackVarStr)

	// 執行上傳大檔案的操作
	result, err := u.UploadFile(context.TODO(),
		&oss.PutObjectRequest{
			Bucket:      oss.Ptr(bucketName),
			Key:         oss.Ptr(objectName),
			Callback:    oss.Ptr(callbackBase64),    // 填寫回調參數
			CallbackVar: oss.Ptr(callbackVarBase64), // 填寫自訂回調參數
		},
		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"
	"fmt"
	"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(&region, "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 = 3            // 設定並行上傳數為3
	})

	// 替換為您的實際本地檔案路徑
	localFile := "/Users/yourLocalPath/yourFileName"

	// 執行上傳大檔案的操作
	result, err := u.UploadFile(context.TODO(),
		&oss.PutObjectRequest{
			Bucket: oss.Ptr(bucketName),
			Key:    oss.Ptr(objectName),
			ProgressFn: func(increment, transferred, total int64) {
				fmt.Printf("increment:%v, transferred:%v, total:%v\n", increment, transferred, total)
			}, // 進度回呼函數,用於顯示上傳進度
		},
		localFile)
	if err != nil {
		log.Fatalf("failed to upload file %v", err)
	}

	// 列印上傳檔案的結果
	log.Printf("upload file result:%#v\n", result)
}

相關文檔