注意事项
本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见OSS访问域名、数据中心、开放端口。
本文以从环境变量读取访问凭证为例。如何配置访问凭证,请参见配置访问凭证。
本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见初始化。
要将文件下载到本地,您必须有oss:GetObject
权限。具体操作,请参见为RAM用户授权自定义的权限策略。
示例代码
以下代码用于将examplebucket
中exampledir
目录下的exampleobject.txt
文件下载到本地D:\localpath\examplefile.txt
。
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
bucketName := "examplebucket"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket: %v", err)
}
objectName := "exampledir/exampleobject.txt"
localFilePath := "D:\\localpath\\examplefile.txt"
err = bucket.GetObjectToFile(objectName, localFilePath)
if err != nil {
log.Fatalf("Failed to download file: %v", err)
}
log.Println("File downloaded successfully.")
}
常见使用场景
当从Bucket中下载单个文件(Object)时,您可以指定基于文件最后修改时间或ETag(文件内容标识符)的条件限制。只有当这些条件得到满足时才会执行下载操作;如果不满足,则会返回错误并且不会触发下载。利用条件下载不仅可以减少不必要的网络传输和资源消耗,还能提高下载效率。
OSS支持的限定条件如下:
参数 | 描述 | 如何设置 |
IfModifiedSince | 如果指定的时间早于实际修改时间,则正常传输文件,否则返回错误(304 Not modified)。 | oss.IfModifiedSince |
IfUnmodifiedSince | 如果指定的时间等于或者晚于文件实际修改时间,则正常传输文件,否则返回错误(412 Precondition failed)。 | oss.IfUnmodifiedSince |
IfMatch | 如果指定的ETag和OSS文件的ETag匹配,则正常传输文件,否则返回错误(412 Precondition failed)。 | oss.IfMatch |
IfNoneMatch | 如果指定的ETag和OSS文件的ETag不匹配,则正常传输文件,否则返回错误(304 Not modified)。 | oss.IfNoneMatch |
以下代码用于限定条件下载。
package main
import (
"log"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
bucketName := "yourBucketName"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket: %v", err)
}
date := time.Date(2023, time.November, 21, 18, 43, 2, 0, time.UTC)
objectName := "yourObjectName"
localFilePath := "LocalFile"
err = bucket.GetObjectToFile(objectName, localFilePath, oss.IfUnmodifiedSince(date))
if err == nil {
log.Fatal("Expected an error when the condition is not met, but got nil")
}
err = bucket.GetObjectToFile(objectName, localFilePath, oss.IfModifiedSince(date))
if err != nil {
log.Fatalf("Failed to download file: %v", err)
}
log.Println("File has been downloaded successfully.")
}
当您在下载文件时,可以使用进度条实时了解下载进度,避免因为等待时间过长而感到不安或怀疑任务是否卡住。
以下代码用于打印从examplebucket下载exampleobject.txt文件的进度条。
package main
import (
"log"
"sync/atomic"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
type OssProgressListener struct {
lastProgress int64
}
func (listener *OssProgressListener) ProgressChanged(event *oss.ProgressEvent) {
switch event.EventType {
case oss.TransferStartedEvent:
log.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
case oss.TransferDataEvent:
if event.TotalBytes != 0 {
progress := int64(event.ConsumedBytes * 100 / event.TotalBytes)
if progress > atomic.LoadInt64(&listener.lastProgress) {
atomic.StoreInt64(&listener.lastProgress, progress)
log.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes %d, %d%%.",
event.ConsumedBytes, event.TotalBytes, progress)
}
}
case oss.TransferCompletedEvent:
log.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
case oss.TransferFailedEvent:
log.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
default:
}
}
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error: %v", err)
}
bucketName := "examplebucket"
objectName := "exampleobject.txt"
localFile := "D:\\localpath\\examplefile.txt"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Error: %v", err)
}
err = bucket.GetObjectToFile(objectName, localFile, oss.Progress(&OssProgressListener{}))
if err != nil {
log.Fatalf("Error: %v", err)
}
log.Println("Transfer Completed.")
}