全部产品
阿里云办公

下载文件

更新时间:2018-08-21 16:28:48

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. }

断点续传下载

当下载大文件时,如果网络不稳定或者程序异常退出,会导致下载失败,甚至重试多次仍无法完成下载。为此OSS提供了断点续传下载功能。

断点续传下载将需要下载的文件分成若干个分片(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. }
本文导读目录