阿里雲團隊努力不懈,力求將最新的技術內容更快地以您最熟悉的語言呈現。本文由簡體中文內容自動轉碼而成,過程無人工干預。阿里雲不保證此自動轉碼的準確性、完整性及時效性。因轉碼造成的任何內容錯誤及因此可能帶來的損失,阿里雲概不負責,敬請見諒。本文内容請以簡體中文版本為準。
全部產品
Search
文件中心

下載檔案

更新時間: Oct 19, 2018

OSS Go SDK提供了豐富的檔案下載方式:

下載過程中,您還可以通過進度條功能查看下載進度。

下載檔案的完整範例程式碼請參見GitHub

流式下載

下載檔案到流

以下代碼用於把指定的OSS檔案下載到流:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "io/ioutil"
  6. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  7. )
  8. func main() {
  9. // 建立OSSClient執行個體。
  10. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  11. if err != nil {
  12. fmt.Println("Error:", err)
  13. os.Exit(-1)
  14. }
  15. // 獲取儲存空間。
  16. bucket, err := client.Bucket("<yourBucketName>")
  17. if err != nil {
  18. fmt.Println("Error:", err)
  19. os.Exit(-1)
  20. }
  21. // 下載檔案到流。
  22. body, err := bucket.GetObject("<yourObjectName>")
  23. if err != nil {
  24. fmt.Println("Error:", err)
  25. os.Exit(-1)
  26. }
  27. // 資料讀取完成後,獲取的流必須關閉,否則會造成連接泄漏,導致請求無連接可用,程式無法正常工作。
  28. defer body.Close()
  29. data, err := ioutil.ReadAll(body)
  30. if err != nil {
  31. fmt.Println("Error:", err)
  32. os.Exit(-1)
  33. }
  34. fmt.Println("data:", string(data))
  35. }

下載檔案到緩存

以下代碼用於把指定的OSS檔案下載到本機快取:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "io"
  6. "bytes"
  7. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  8. )
  9. func main() {
  10. // 建立OSSClient執行個體。
  11. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  12. if err != nil {
  13. fmt.Println("Error:", err)
  14. os.Exit(-1)
  15. }
  16. // 獲取儲存空間。
  17. bucket, err := client.Bucket("<yourBucketName>")
  18. if err != nil {
  19. fmt.Println("Error:", err)
  20. os.Exit(-1)
  21. }
  22. // 下載檔案到緩存。
  23. body, err := bucket.GetObject("<yourObjectName>")
  24. if err != nil {
  25. fmt.Println("Error:", err)
  26. os.Exit(-1)
  27. }
  28. defer body.Close()
  29. buf := new(bytes.Buffer)
  30. io.Copy(buf, body)
  31. fmt.Println("buf:", buf)
  32. }

下載檔案到本地檔案流

以下代碼用於把指定的OSS檔案下載到本地檔案流:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "io"
  6. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  7. )
  8. func main() {
  9. // 建立OSSClient執行個體。
  10. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  11. if err != nil {
  12. fmt.Println("Error:", err)
  13. os.Exit(-1)
  14. }
  15. // 獲取儲存空間。
  16. bucket, err := client.Bucket("<yourBucketName>")
  17. if err != nil {
  18. fmt.Println("Error:", err)
  19. os.Exit(-1)
  20. }
  21. // 下載檔案到本地檔案流。
  22. body, err := bucket.GetObject("<yourObjectName>")
  23. if err != nil {
  24. fmt.Println("Error:", err)
  25. os.Exit(-1)
  26. }
  27. defer body.Close()
  28. fd, err := os.OpenFile("LocalFile", os.O_WRONLY|os.O_CREATE, 0660)
  29. if err != nil {
  30. fmt.Println("Error:", err)
  31. os.Exit(-1)
  32. }
  33. defer fd.Close()
  34. io.Copy(fd, body)
  35. }

下載到本地檔案

以下代碼用於把指定的OSS檔案下載到本地檔案:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  6. )
  7. func main() {
  8. // 建立OSSClient執行個體。
  9. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  10. if err != nil {
  11. fmt.Println("Error:", err)
  12. os.Exit(-1)
  13. }
  14. // 獲取儲存空間。
  15. bucket, err := client.Bucket("<yourBucketName>")
  16. if err != nil {
  17. fmt.Println("Error:", err)
  18. os.Exit(-1)
  19. }
  20. // 下載檔案到本地檔案。
  21. err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile")
  22. if err != nil {
  23. fmt.Println("Error:", err)
  24. os.Exit(-1)
  25. }
  26. }

分區下載

分區上傳是指將要上傳的檔案分成若干個分區(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檔案。
- 下載時限定條件,請參見限定條件下載

以下代碼用於斷點續傳下載:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  6. )
  7. func main() {
  8. // 建立OSSClient執行個體。
  9. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  10. if err != nil {
  11. fmt.Println("Error:", err)
  12. os.Exit(-1)
  13. }
  14. // 獲取儲存空間。
  15. bucket, err := client.Bucket("<yourBucketName>")
  16. if err != nil {
  17. fmt.Println("Error:", err)
  18. os.Exit(-1)
  19. }
  20. // 分區下載。3個協程並發下載分區,開啟斷點續傳下載。
  21. // 其中"<yourObjectName>"為objectKey, "LocalFile"為filePath,100*1024為partSize。
  22. err = bucket.DownloadFile("<yourObjectName>", "LocalFile", 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
  23. if err != nil {
  24. fmt.Println("Error:", err)
  25. os.Exit(-1)
  26. }
  27. }

限定條件下載

下載檔案時,可以指定一個或多個限定條件。滿足限定條件則下載,不滿足則返回錯誤,不下載。可以使用的限定條件如下:

參數 描述 如何設定
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方法獲取。

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  7. )
  8. func main() {
  9. // 建立OSSClient執行個體。
  10. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  11. if err != nil {
  12. fmt.Println("Error:", err)
  13. os.Exit(-1)
  14. }
  15. // 獲取儲存空間。
  16. bucket, err := client.Bucket("<yourBucketName>")
  17. if err != nil {
  18. fmt.Println("Error:", err)
  19. os.Exit(-1)
  20. }
  21. // 設定時間限定條件。
  22. date := time.Date(2015, time.November, 10, 23, 0, 0, 0, time.UTC)
  23. // 限定條件不滿足,不下載檔案。
  24. err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile", oss.IfModifiedSince(date))
  25. if err == nil {
  26. fmt.Println("Error:", err)
  27. os.Exit(-1)
  28. }
  29. // 滿足限定條件,下載檔案。
  30. err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile", oss.IfUnmodifiedSince(date))
  31. if err != nil {
  32. fmt.Println("Error:", err)
  33. os.Exit(-1)
  34. }
  35. }

檔案壓縮下載

檔案可以壓縮下載,目前支援GZIP壓縮。Bucket.GetObject和Bucket.GetObjectToFile支援壓縮功能。

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  6. )
  7. func main() {
  8. // 建立OSSClient執行個體。
  9. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  10. if err != nil {
  11. fmt.Println("Error:", err)
  12. os.Exit(-1)
  13. }
  14. // 獲取儲存空間。
  15. bucket, err := client.Bucket("<yourBucketName>")
  16. if err != nil {
  17. fmt.Println("Error:", err)
  18. os.Exit(-1)
  19. }
  20. // 檔案壓縮下載。
  21. err = bucket.GetObjectToFile("<yourObjectName>", "LocalFile.gzip", oss.AcceptEncoding("gzip"))
  22. if err != nil {
  23. fmt.Println("Error:", err)
  24. os.Exit(-1)
  25. }
  26. }

進度條

進度條用於指示上傳或下載的進度。下面的代碼以Bucket.GetObjectToFile方法為例,介紹如何使用進度條。

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  6. )
  7. // 定義進度條監聽器。
  8. type OssProgressListener struct {
  9. }
  10. // 定義進度變更事件處理函數。
  11. func (listener *OssProgressListener) ProgressChanged(event *oss.ProgressEvent) {
  12. switch event.EventType {
  13. case oss.TransferStartedEvent:
  14. fmt.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes %d.\n",
  15. event.ConsumedBytes, event.TotalBytes)
  16. case oss.TransferDataEvent:
  17. fmt.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes %d, %d%%.",
  18. event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
  19. case oss.TransferCompletedEvent:
  20. fmt.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes %d.\n",
  21. event.ConsumedBytes, event.TotalBytes)
  22. case oss.TransferFailedEvent:
  23. fmt.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes %d.\n",
  24. event.ConsumedBytes, event.TotalBytes)
  25. default:
  26. }
  27. }
  28. func main() {
  29. // 建立OSSClient執行個體。
  30. client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  31. if err != nil {
  32. fmt.Println("Error:", err)
  33. os.Exit(-1)
  34. }
  35. bucketName := "<yourBucketName>"
  36. objectName := "<yourObjectName>"
  37. localFile := "<yourLocalFile>"
  38. // 獲取儲存空間。
  39. bucket, err := client.Bucket(bucketName)
  40. if err != nil {
  41. fmt.Println("Error:", err)
  42. os.Exit(-1)
  43. }
  44. // 帶進度條的下載。
  45. err = bucket.GetObjectToFile(objectName, localFile, oss.Progress(&OssProgressListener{}))
  46. if err != nil {
  47. fmt.Println("Error:", err)
  48. os.Exit(-1)
  49. }
  50. fmt.Println("Transfer Completed.")
  51. }