OSS Go SDK提供了豐富的檔案下載方式:
下載過程中,您還可以通過進度條功能查看下載進度。
下載檔案的完整範例程式碼請參見GitHub。
流式下載
下載檔案到流
以下代碼用於把指定的OSS檔案下載到流:
package main
import (
"fmt"
"os"
"io/ioutil"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 下載檔案到流。
body, err := bucket.GetObject("<yourObjectName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 資料讀取完成後,獲取的流必須關閉,否則會造成連接泄漏,導致請求無連接可用,程式無法正常工作。
defer body.Close()
data, err := ioutil.ReadAll(body)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("data:", string(data))
}
下載檔案到緩存
以下代碼用於把指定的OSS檔案下載到本機快取:
package main
import (
"fmt"
"os"
"io"
"bytes"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 下載檔案到緩存。
body, err := bucket.GetObject("<yourObjectName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
defer body.Close()
buf := new(bytes.Buffer)
io.Copy(buf, body)
fmt.Println("buf:", buf)
}
下載檔案到本地檔案流
以下代碼用於把指定的OSS檔案下載到本地檔案流:
package main
import (
"fmt"
"os"
"io"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 下載檔案到本地檔案流。
body, err := bucket.GetObject("<yourObjectName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
defer body.Close()
fd, err := os.OpenFile("LocalFile", os.O_WRONLY|os.O_CREATE, 0660)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
defer fd.Close()
io.Copy(fd, body)
}
下載到本地檔案
以下代碼用於把指定的OSS檔案下載到本地檔案:
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 下載檔案到本地檔案。
err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
}
分區下載
分區上傳是指將要上傳的檔案分成若干個分區(Part)分別上傳,所有分區都上傳完成後,將所有分區合并成完整的檔案,完成整個檔案的上傳。在上傳的過程中會在Checkpoint檔案中記錄當前上傳的進度資訊,如果上傳過程中某一分區上傳失敗,再次上傳時會從Checkpoint檔案中記錄的點繼續上傳,從而達到斷點續傳下載的效果。上傳完成後,Checkpoint檔案會被刪除。
說明:
- SDK會將下載的中間狀態資訊記錄在Checkpoint檔案中,所以要確保程式對Checkpoint檔案有寫入權限。Checkpoint攜帶了校驗資訊,請不要修改。如果Checkpoint檔案損壞則會重新下載檔案。
- 如果下載過程中待下載的OSS檔案發生了改變(ETag改變),或者part檔案丟失或被修改,則會重新下載檔案。
您可以使用Bucket.DownloadFile
實現斷點續傳下載。可設定的參數如下:
參數 | 說明 |
---|---|
objectKey | 要下載的OSS檔案名稱。 |
filePath | 下載到本地檔案的路徑。 |
partSize | 下載分區大小,取值範圍為1B~5GB。 |
options | 可選項,包括: - Routines:指定分區下載的並發數。預設是1,即不使用並發下載。 - Checkpoint:指定是否開啟斷點續傳下載功能以及設定Checkpoint檔案。預設關閉斷點續傳下載功能。例如 oss.Checkpoint(true, "") , 表示開啟斷點續傳下載功能,並且Checkpoint檔案為與本地檔案同目錄下的file.cp ,其中file 是本地檔案名稱。您也可以使用oss.Checkpoint(true, "your-cp-file.cp") 指定Checkpoint檔案。 - 下載時限定條件,請參見限定條件下載。 |
以下代碼用於斷點續傳下載:
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 分區下載。3個協程並發下載分區,開啟斷點續傳下載。
// 其中"<yourObjectName>"為objectKey, "LocalFile"為filePath,100*1024為partSize。
err = bucket.DownloadFile("<yourObjectName>", "LocalFile", 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
}
限定條件下載
下載檔案時,可以指定一個或多個限定條件。滿足限定條件則下載,不滿足則返回錯誤,不下載。可以使用的限定條件如下:
參數 | 描述 | 如何設定 |
---|---|---|
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 |
IfModifiedSince和IfUnmodifiedSince可以同時存在。IfMatch和IfNoneMatch可以同時存在。
ETag可以通過Bucket.GetObjectDetailedMeta方法獲取。
package main
import (
"fmt"
"os"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 設定時間限定條件。
date := time.Date(2015, time.November, 10, 23, 0, 0, 0, time.UTC)
// 限定條件不滿足,不下載檔案。
err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile", oss.IfModifiedSince(date))
if err == nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 滿足限定條件,下載檔案。
err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile", oss.IfUnmodifiedSince(date))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
}
檔案壓縮下載
檔案可以壓縮下載,目前支援GZIP壓縮。Bucket.GetObject和Bucket.GetObjectToFile支援壓縮功能。
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 獲取儲存空間。
bucket, err := client.Bucket("<yourBucketName>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 檔案壓縮下載。
err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile.gzip", oss.AcceptEncoding("gzip"))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
}
進度條
進度條用於指示上傳或下載的進度。下面的代碼以Bucket.GetObjectToFile方法為例,介紹如何使用進度條。
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
// 定義進度條監聽器。
type OssProgressListener struct {
}
// 定義進度變更事件處理函數。
func (listener *OssProgressListener) ProgressChanged(event *oss.ProgressEvent) {
switch event.EventType {
case oss.TransferStartedEvent:
fmt.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
case oss.TransferDataEvent:
fmt.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes %d, %d%%.",
event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
case oss.TransferCompletedEvent:
fmt.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
case oss.TransferFailedEvent:
fmt.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes %d.\n",
event.ConsumedBytes, event.TotalBytes)
default:
}
}
func main() {
// 建立OSSClient執行個體。
client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
bucketName := "<yourBucketName>"
objectName := "<yourObjectName>"
localFile := "<yourLocalFile>"
// 獲取儲存空間。
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 帶進度條的下載。
err = bucket.GetObjectToFile(objectName, localFile, oss.Progress(&OssProgressListener{}))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("Transfer Completed.")
}