Downloader in OSS SDK for Go 2.0

Updated at:

This topic describes how to download objects by using the Downloader module of Object Storage Service (OSS) SDK for Go V2.

Usage notes

  • The sample code in this topic uses the region ID cn-hangzhou of the China (Hangzhou) region. By default, the public endpoint is used to access resources in a bucket. If you want to access resources in the bucket from other Alibaba Cloud services in the same region in which the bucket is located, use an internal endpoint. For more information about OSS regions and endpoints, see Regions and endpoints.

  • In this topic, access credentials are obtained from environment variables. For more information about how to configure the access credentials, see Configure access credentials.

  • To download a object, you must have the oss:GetObject permission. For more information, see Grant a custom policy.

Methods

Downloader

The Downloader module of OSS SDK for Go V2 provides a universal operation for downloading objects and hides the operation implementation details.

  • The Downloader uses the underlying range download capability to split a object into parts and downloads the parts in parallel to improve download performance.

  • The Downloader allows you to perform a resumable download. A resumable download records the download progress and allows you to resume the download from the position that is recorded in the checkpoint file in case of download interruptions due to factors such as network disconnections or an unexpected program exit. You can resume the download even if multiple download attempts fail.

The following lines provide the common methods of the Downloader module:

type Downloader struct {
  ...
}

// Create a Downloader.
func (c *Client) NewDownloader(optFns ...func(*DownloaderOptions)) *Downloader

// Download a object.
func (d *Downloader) DownloadFile(ctx context.Context, request *GetObjectRequest, filePath string, optFns ...func(*DownloaderOptions)) (result *DownloadResult, err error)

Request parameters

Parameter

Type

Description

ctx

context.Context

The context of the request, which can be used to specify the total duration of the request.

request

*GetObjectRequest

The parameters of a specific API operation. For more information, see GetObjectRequest.

filePath

string

The path of the local file.

optFns

...func(*DownloaderOptions)

The optional parameters.

Common parameters of DownloaderOptions

Parameter

Type

Description

PartSize

int64

The part size. The default part size is 6 MiB.

ParallelNum

int

The number of parts that can be downloaded in parallel. The default value is 3. The setting is specific to this call only and does not apply globally.

EnableCheckpoint

bool

Specifies whether to record checkpoint information. By default, checkpoint information is not recorded.

CheckpointDir

string

The path of the checkpoint file. This parameter is valid only if EnableCheckpoint is set to true. Example: /local/dir/.

VerifyData

bool

Specifies whether to verify the CRC-64 of the downloaded object when the download is resumed. By default, the CRC-64 is not verified. This parameter is valid only if EnableCheckpoint is set to true.

UseTempFile

bool

Specifies whether to use a temporary file when you download an object. A temporary file is used by default. The object is downloaded to the temporary file. Then, the temporary file is renamed to the name of the destination file.

When you use NewDownloader to create a Downloader, you can specify several configuration parameters to specify custom object download behaviors. You can also specify multiple configuration parameters to specify custom object download behaviors each time you call a download operation.

  • Specify configuration parameters for Downloader

    d := client.NewDownloader(func(do *oss.DownloaderOptions) {
      do.PartSize = 10 * 1024 * 1024
    })
  • Specify configuration parameters for each download request

    request := &oss.GetObjectRequest{Bucket: oss.Ptr("bucket"), Key: oss.Ptr("key")}
    d.DownloadFile(context.TODO(), request, "/local/dir/example", func(do *oss.DownloaderOptions) {
      do.PartSize = 10 * 1024 * 1024
    })

Sample code

The following sample code provides an example on how to download an object to a local device.

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define the global variables.
var (
	region     string // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Use the init function to initialize parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "src-object", "", "The name of the source object.")
}

func main() {
	// Parse parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the source object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, src object name required")
	}

	// Create an OSS client configuration.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Create a Downloader.
	d := client.NewDownloader()

	// Create a request to download the object.
	request := &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName), // The name of the bucket.
		Key:    oss.Ptr(objectName), // The name of the object.
	}

	// The path of the local file.
	localFile := "local-file"

	// Execute the request to download the object.
	result, err := d.DownloadFile(context.TODO(), request, localFile)
	if err != nil {
		log.Fatalf("failed to download file %v", err)
	}

	// Print the success response.
	log.Printf("download file %s to local-file successfully, size: %d", objectName, result.Written)
}

Common scenarios

Use the Downloader to specify the size and the number of parts that can be downloaded in parallel

The following sample code provides an example on how to specify the size and the number of parts that can be downloaded in parallel by configuring the parameters in DownloaderOptions:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define the global variables.
var (
	region     string // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Use the init function to initialize parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "src-object", "", "The name of the source object.")
}

func main() {
	// Parse parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the source object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, src object name required")
	}

	// Create an OSS client configuration.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Create a Downloader.
	d := client.NewDownloader()

	// Create a request to download the object.
	request := &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName), // The name of the bucket.
		Key:    oss.Ptr(objectName), // The name of the object.
	}

	// The path of the local file.
	localFile := "local-file"

	// Specify downloader options.
	downloaderOptions := func(do *oss.DownloaderOptions) {
		do.PartSize = 20 * 1024 * 1024 // Set the part size to 20 MiB.
		do.ParallelNum = 6            // Set the number of parts that can be downloaded in parallel to 6.
	}

	// Execute the request to download the object.
	result, err := d.DownloadFile(context.TODO(), request, localFile, downloaderOptions)
	if err != nil {
		log.Fatalf("failed to download file %v", err)
	}

	// Print the success response.
	log.Printf("download file %s to local-file successfully, size: %d", objectName, result.Written)
}

Use the Downloader to enable resumable download

The following sample code provides an example on how to perform a resumable download by configuring DownloaderOptions for a Downloader:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define the global variables.
var (
	region     string // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
)

// Use the init function to initialize parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "src-object", "", "The name of the source object.")
}

func main() {
	// Parse parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the source object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, src object name required")
	}

	// Create an OSS client configuration.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Create a Downloader.
	d := client.NewDownloader()

	// Create a request to download the object.
	request := &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName), // The name of the bucket.
		Key:    oss.Ptr(objectName), // The name of the object.
	}

	// The path of the local file.
	localFile := "local-file"

	// Specify downloader options.
	downloaderOptions := func(do *oss.DownloaderOptions) {
		do.EnableCheckpoint = true        // Enable checkpoint recording.
		do.CheckpointDir = "./checkpoint" // Specify the path of the checkpoint file.
		do.UseTempFile = true             // Specify the use of a temporary file.
	}

	// Execute the request to download the object.
	result, err := d.DownloadFile(context.TODO(), request, localFile, downloaderOptions)
	if err != nil {
		log.Fatalf("failed to download file %v", err)
	}

	// Print the success response.
	log.Printf("download file %s to local-file successfully, size: %d", objectName, result.Written)
}

References