更新时间:2026-04-07 GMT+08:00
分享

上传对象-进度条(Go SDK)

功能说明

获取上传对象进度是指在进行对象上传操作时,实时监控并获取上传进度的功能。通过实现进度监听接口,可以获取到上传任务的开始、数据传输中、上传完成或失败等状态信息,以及已上传字节数和总字节数。

接口约束

  • 您必须是桶拥有者或拥有上传对象的权限,才能上传对象。建议使用IAM或桶策略进行授权,如果使用IAM则需授予obs:object:PutObject权限,如果使用桶策略则需授予PutObject权限。相关授权方式介绍可参见OBS权限控制概述,配置方式详见使用IAM自定义策略配置对象策略
  • OBS支持的Region与Endpoint的对应关系,详细信息请参见地区与终端节点

方法定义

obs.WithProgress(progressListener ProgressListener)

请求参数说明

表1 请求参数列表

参数名称

参数类型

是否必选

描述

progressListener

interface

必选

参数解释

进度监听器。需要实现以下方法:

ProgressChanged(event *表2 ProgressEvent)

表2 ProgressEvent

参数名称

原始值

说明

TransferStartedEvent

1

上传开始时触发

TransferDataEvent

2

数据传输过程中持续触发

TransferCompletedEvent

3

上传成功完成时触发

TransferFailedEvent

4

上传失败时触发

返回结果说明

返回结果参考原有方法函数调用,参考代码示例

代码示例-流式上传进度监控

本示例用于流式上传到examplebucket桶中的example/objectname,并监听上传进度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 引入依赖包
import (
     "fmt"
     "bytes"
     "encoding/base64"
     "encoding/json"
     "strings"
     obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)

// 定义进度条监听器。
type ObsProgressListener struct {
}
// 定义进度变更事件处理函数。
func (listener *ObsProgressListener) ProgressChanged(event *obs.ProgressEvent) {
    switch event.EventType {
    case obs.TransferStartedEvent:
        fmt.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    case obs.TransferDataEvent:
        fmt.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes %d, %d%%.\n",
            event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
    case obs.TransferCompletedEvent:
        fmt.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    case obs.TransferFailedEvent:
        fmt.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    default:
    }
}

func main() {
    //推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK,也可以使用其他外部引入方式传入。
    // securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例,其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建obsClient实例
    // 如果使用临时AKSK和SecurityToken访问OBS,需要在创建实例时通过obs.WithSecurityToken方法指定securityToken值。
    obsClient, err := obs.New(ak, sk, endPoint/*, obs.WithSecurityToken(securityToken)*/)

    input := &obs.PutObjectInput{}
    // 指定存储桶名称
    input.Bucket = "bucketname"
    // 指定上传对象,此处以 example/objectname 为例。
    input.Key = "objectname"
    input.Body = strings.NewReader("Hello OBS")
    output, err := obsClient.PutObject(input, obs.WithProgress(&ObsProgressListener{})
)
    if err == nil {
        // 必须调用该方法
        defer output.CloseCallbackBody()
        fmt.Printf("RequestId:%s\n", output.RequestId)
        fmt.Printf("ETag:%s\n", output.ETag)
        p := make([]byte, 1024)
        var readErr error
        var readCount int
        // 读取回调内容
        for {
            readCount, readErr = output.ReadCallbackBody(p)
            if readCount > 0 {
                fmt.Printf("%s", p[:readCount])
            }
            if readErr != nil {
                break
            }
        }
    } else if obsError, ok := err.(obs.ObsError); ok {
        fmt.Printf("Code:%s\n", obsError.Code)
        fmt.Printf("Message:%s\n", obsError.Message)
    }
}

代码示例-断点续传进度监控

本示例用于断点上传到examplebucket桶中的example/objectname,并监听上传进度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 引入依赖包
import (
     "fmt"
     "bytes"
     "encoding/base64"
     "encoding/json"
     "strings"
     obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)

// 定义进度条监听器。
type ObsProgressListener struct {
}
// 定义进度变更事件处理函数。
func (listener *ObsProgressListener) ProgressChanged(event *obs.ProgressEvent) {
    switch event.EventType {
    case obs.TransferStartedEvent:
        fmt.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    case obs.TransferDataEvent:
        fmt.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes %d, %d%%.\n",
            event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
    case obs.TransferCompletedEvent:
        fmt.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    case obs.TransferFailedEvent:
        fmt.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes %d.\n",
            event.ConsumedBytes, event.TotalBytes)
    default:
    }
}

func main() {
    //推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html。
    ak := os.Getenv("AccessKeyID")
    sk := os.Getenv("SecretAccessKey")
    // 【可选】如果使用临时AK/SK和SecurityToken访问OBS,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK,也可以使用其他外部引入方式传入。
    // securityToken := os.Getenv("SecurityToken")
    // endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例,其他地区请按实际情况填写。
    endPoint := "https://obs.cn-north-4.myhuaweicloud.com"
    // 创建obsClient实例
    // 如果使用临时AKSK和SecurityToken访问OBS,需要在创建实例时通过obs.WithSecurityToken方法指定securityToken值。
    obsClient, err := obs.New(ak, sk, endPoint/*, obs.WithSecurityToken(securityToken)*/)

    input := &obs.UploadFileInput{}
    // 指定存储桶名称
    input.Bucket = "bucketname"
    // 指定上传对象,此处以 example/objectname 为例。
    input.Key = "objectname"
    // 指定待上传的本地文件,此处以/tmp/objectname为例。
    input.UploadFile = "/tmp/objectname"
    // 指定是否开启断点续传模式,此处以true为例。默认为False,表示不开启。
    input.EnableCheckpoint = true
    // 指定分段大小,单位字节。此处以每段9M为例。
    input.PartSize = 9 * 1024 * 1024
    // 指定分段上传时的最大并发数,此处以并发数5为例
    input.TaskNum = 5
    output, err := obsClient.UploadFile(input, obs.WithProgress(&ObsProgressListener{})
    if err == nil {
        // 必须调用该方法
        defer output.CloseCallbackBody()
        fmt.Printf("RequestId:%s\n", output.RequestId)
        fmt.Printf("ETag:%s\n", output.ETag)
        p := make([]byte, 1024)
        var readErr error
        var readCount int
        // 读取回调内容
        for {
            readCount, readErr = output.ReadCallbackBody(p)
            if readCount > 0 {
                fmt.Printf("%s", p[:readCount])
            }
            if readErr != nil {
                break
            }
        }
    } else if obsError, ok := err.(obs.ObsError); ok {
        fmt.Printf("Code:%s\n", obsError.Code)
        fmt.Printf("Message:%s\n", obsError.Message)
    }
}

相关链接

相关文档