如何借助OCI transfer包跟踪OCI对象存储的文件上传进度?
OCI Object Storage文件上传进度显示问题解决
我正在搭建一个上传至OCI Object Storage的文件上传器,目前功能正常,但无法查看当前的上传进度。原函数代码如下:
uploadObjectStorage := func(filePath, fileName string) { file, err := os.Open(filePath) if err != nil { panic("Could not open file for read") } ociUploadRequest := transfer.UploadRequest{ NamespaceName: oci_namespace, BucketName: oci_bucketname, ObjectName: common.String(fileName), RequestMetadata: common.RequestMetadata{ RetryPolicy: &oci_retry, }, } req := transfer.UploadStreamRequest{ UploadRequest: ociUploadRequest, StreamReader: file, } _, err = transfer.NewUploadManager().UploadStream(context.Background(), req) if err != nil { panic(err) } }
已知存在transfer.UploadCallBack类型,会在分片上传成功后被调用,但无法使其正常工作。
环境信息:
- Go版本:go1.21.1
- 系统:windows/amd64
- oci-go-sdk版本:v65.49.1
解决步骤
要启用上传进度回调,需要完成两个关键操作:设置文件总大小、绑定回调函数。以下是修改后的完整代码:
uploadObjectStorage := func(filePath, fileName string) { file, err := os.Open(filePath) if err != nil { panic("Could not open file for read") } defer file.Close() // 确保文件最终关闭 // 获取文件总大小,用于进度计算 fileInfo, err := file.Stat() if err != nil { panic("Could not retrieve file information") } totalFileSize := fileInfo.Size() // 自定义上传回调函数,符合transfer.UploadCallBack签名 uploadCallback := func(bytesUploaded int64, totalBytes int64) { progress := (float64(bytesUploaded) / float64(totalBytes)) * 100 // 使用\r实现单行刷新进度 fmt.Printf("\r上传进度:%.2f%% (%d/%d 字节)", progress, bytesUploaded, totalBytes) if bytesUploaded == totalBytes { fmt.Println("\n上传完成!") } } ociUploadRequest := transfer.UploadRequest{ NamespaceName: oci_namespace, BucketName: oci_bucketname, ObjectName: common.String(fileName), ContentLength: totalFileSize, // 必须设置,否则回调无法获取总字节数 RequestMetadata: common.RequestMetadata{ RetryPolicy: &oci_retry, }, Callback: uploadCallback, // 绑定回调函数 } req := transfer.UploadStreamRequest{ UploadRequest: ociUploadRequest, StreamReader: file, } _, err = transfer.NewUploadManager().UploadStream(context.Background(), req) if err != nil { panic(err) } }
关键说明
- 设置ContentLength:流式上传时SDK无法自动获取文件总大小,必须通过
file.Stat()获取后赋值给UploadRequest.ContentLength,否则回调中的totalBytes会为0,无法计算有效进度。 - 回调函数签名:必须严格遵循
func(int64, int64)的格式,第一个参数是已上传字节数,第二个是总字节数。 - 进度显示优化:使用
\r可以让进度在同一行持续刷新,避免控制台输出过多冗余内容。
内容的提问来源于stack exchange,提问作者guiarnaldo
相关产品推荐
相关产品推荐

