You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助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)
    }
}

关键说明

  1. 设置ContentLength:流式上传时SDK无法自动获取文件总大小,必须通过file.Stat()获取后赋值给UploadRequest.ContentLength,否则回调中的totalBytes会为0,无法计算有效进度。
  2. 回调函数签名:必须严格遵循func(int64, int64)的格式,第一个参数是已上传字节数,第二个是总字节数。
  3. 进度显示优化:使用\r可以让进度在同一行持续刷新,避免控制台输出过多冗余内容。

内容的提问来源于stack exchange,提问作者guiarnaldo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:50:05