Amazon S3 examples using SDK for Go V2 - AWS SDK Code Examples

There are more AWS SDK examples available in the AWS Doc SDK Examples GitHub repo.

Amazon S3 examples using SDK for Go V2

The following code examples show you how to perform actions and implement common scenarios by using the AWS SDK for Go V2 with Amazon S3.

Actions are code excerpts from larger programs and must be run in context. While actions show you how to call individual service functions, you can see actions in context in their related scenarios and cross-service examples.

Scenarios are code examples that show you how to accomplish a specific task by calling multiple functions within the same service.

Each example includes a link to GitHub, where you can find instructions on how to set up and run the code in context.

Get started

The following code examples show how to get started using Amazon S3.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

package main import ( "context" "fmt" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) // main uses the AWS SDK for Go V2 to create an Amazon Simple Storage Service // (Amazon S3) client and list up to 10 buckets in your account. // This example uses the default settings specified in your shared credentials // and config files. func main() { sdkConfig, err := config.LoadDefaultConfig(context.TODO()) if err != nil { fmt.Println("Couldn't load default configuration. Have you set up your AWS account?") fmt.Println(err) return } s3Client := s3.NewFromConfig(sdkConfig) count := 10 fmt.Printf("Let's list up to %v buckets for your account.\n", count) result, err := s3Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{}) if err != nil { fmt.Printf("Couldn't list buckets for your account. Here's why: %v\n", err) return } if len(result.Buckets) == 0 { fmt.Println("You don't have any buckets!") } else { if count > len(result.Buckets) { count = len(result.Buckets) } for _, bucket := range result.Buckets[:count] { fmt.Printf("\t%v\n", *bucket.Name) } } }
  • For API details, see ListBuckets in AWS SDK for Go API Reference.

Actions

The following code example shows how to use CopyObject.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // CopyToBucket copies an object in a bucket to another bucket. func (basics BucketBasics) CopyToBucket(sourceBucket string, destinationBucket string, objectKey string) error { _, err := basics.S3Client.CopyObject(context.TODO(), &s3.CopyObjectInput{ Bucket: aws.String(destinationBucket), CopySource: aws.String(fmt.Sprintf("%v/%v", sourceBucket, objectKey)), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't copy object from %v:%v to %v:%v. Here's why: %v\n", sourceBucket, objectKey, destinationBucket, objectKey, err) } return err }
  • For API details, see CopyObject in AWS SDK for Go API Reference.

The following code example shows how to use CreateBucket.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // CreateBucket creates a bucket with the specified name in the specified Region. func (basics BucketBasics) CreateBucket(name string, region string) error { _, err := basics.S3Client.CreateBucket(context.TODO(), &s3.CreateBucketInput{ Bucket: aws.String(name), CreateBucketConfiguration: &types.CreateBucketConfiguration{ LocationConstraint: types.BucketLocationConstraint(region), }, }) if err != nil { log.Printf("Couldn't create bucket %v in Region %v. Here's why: %v\n", name, region, err) } return err }
  • For API details, see CreateBucket in AWS SDK for Go API Reference.

The following code example shows how to use DeleteBucket.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // DeleteBucket deletes a bucket. The bucket must be empty or an error is returned. func (basics BucketBasics) DeleteBucket(bucketName string) error { _, err := basics.S3Client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{ Bucket: aws.String(bucketName)}) if err != nil { log.Printf("Couldn't delete bucket %v. Here's why: %v\n", bucketName, err) } return err }
  • For API details, see DeleteBucket in AWS SDK for Go API Reference.

The following code example shows how to use DeleteObjects.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // DeleteObjects deletes a list of objects from a bucket. func (basics BucketBasics) DeleteObjects(bucketName string, objectKeys []string) error { var objectIds []types.ObjectIdentifier for _, key := range objectKeys { objectIds = append(objectIds, types.ObjectIdentifier{Key: aws.String(key)}) } output, err := basics.S3Client.DeleteObjects(context.TODO(), &s3.DeleteObjectsInput{ Bucket: aws.String(bucketName), Delete: &types.Delete{Objects: objectIds}, }) if err != nil { log.Printf("Couldn't delete objects from bucket %v. Here's why: %v\n", bucketName, err) } else { log.Printf("Deleted %v objects.\n", len(output.Deleted)) } return err }
  • For API details, see DeleteObjects in AWS SDK for Go API Reference.

The following code example shows how to use GetObject.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // DownloadFile gets an object from a bucket and stores it in a local file. func (basics BucketBasics) DownloadFile(bucketName string, objectKey string, fileName string) error { result, err := basics.S3Client.GetObject(context.TODO(), &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't get object %v:%v. Here's why: %v\n", bucketName, objectKey, err) return err } defer result.Body.Close() file, err := os.Create(fileName) if err != nil { log.Printf("Couldn't create file %v. Here's why: %v\n", fileName, err) return err } defer file.Close() body, err := io.ReadAll(result.Body) if err != nil { log.Printf("Couldn't read object body from %v. Here's why: %v\n", objectKey, err) } _, err = file.Write(body) return err }
  • For API details, see GetObject in AWS SDK for Go API Reference.

The following code example shows how to use HeadBucket.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // BucketExists checks whether a bucket exists in the current account. func (basics BucketBasics) BucketExists(bucketName string) (bool, error) { _, err := basics.S3Client.HeadBucket(context.TODO(), &s3.HeadBucketInput{ Bucket: aws.String(bucketName), }) exists := true if err != nil { var apiError smithy.APIError if errors.As(err, &apiError) { switch apiError.(type) { case *types.NotFound: log.Printf("Bucket %v is available.\n", bucketName) exists = false err = nil default: log.Printf("Either you don't have access to bucket %v or another error occurred. "+ "Here's what happened: %v\n", bucketName, err) } } } else { log.Printf("Bucket %v exists and you already own it.", bucketName) } return exists, err }
  • For API details, see HeadBucket in AWS SDK for Go API Reference.

The following code example shows how to use ListBuckets.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // ListBuckets lists the buckets in the current account. func (basics BucketBasics) ListBuckets() ([]types.Bucket, error) { result, err := basics.S3Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{}) var buckets []types.Bucket if err != nil { log.Printf("Couldn't list buckets for your account. Here's why: %v\n", err) } else { buckets = result.Buckets } return buckets, err }
  • For API details, see ListBuckets in AWS SDK for Go API Reference.

The following code example shows how to use ListObjectsV2.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // ListObjects lists the objects in a bucket. func (basics BucketBasics) ListObjects(bucketName string) ([]types.Object, error) { result, err := basics.S3Client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{ Bucket: aws.String(bucketName), }) var contents []types.Object if err != nil { log.Printf("Couldn't list objects in bucket %v. Here's why: %v\n", bucketName, err) } else { contents = result.Contents } return contents, err }
  • For API details, see ListObjectsV2 in AWS SDK for Go API Reference.

The following code example shows how to use PutObject.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // UploadFile reads from a file and puts the data into an object in a bucket. func (basics BucketBasics) UploadFile(bucketName string, objectKey string, fileName string) error { file, err := os.Open(fileName) if err != nil { log.Printf("Couldn't open file %v to upload. Here's why: %v\n", fileName, err) } else { defer file.Close() _, err = basics.S3Client.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), Body: file, }) if err != nil { log.Printf("Couldn't upload file %v to %v:%v. Here's why: %v\n", fileName, bucketName, objectKey, err) } } return err }
  • For API details, see PutObject in AWS SDK for Go API Reference.

Scenarios

The following code example shows how to create a presigned URL for Amazon S3 and upload an object.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

Create functions that wrap S3 presigning actions.

// Presigner encapsulates the Amazon Simple Storage Service (Amazon S3) presign actions // used in the examples. // It contains PresignClient, a client that is used to presign requests to Amazon S3. // Presigned requests contain temporary credentials and can be made from any HTTP client. type Presigner struct { PresignClient *s3.PresignClient } // GetObject makes a presigned request that can be used to get an object from a bucket. // The presigned request is valid for the specified number of seconds. func (presigner Presigner) GetObject( bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) { request, err := presigner.PresignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }, func(opts *s3.PresignOptions) { opts.Expires = time.Duration(lifetimeSecs * int64(time.Second)) }) if err != nil { log.Printf("Couldn't get a presigned request to get %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return request, err } // PutObject makes a presigned request that can be used to put an object in a bucket. // The presigned request is valid for the specified number of seconds. func (presigner Presigner) PutObject( bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) { request, err := presigner.PresignClient.PresignPutObject(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }, func(opts *s3.PresignOptions) { opts.Expires = time.Duration(lifetimeSecs * int64(time.Second)) }) if err != nil { log.Printf("Couldn't get a presigned request to put %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return request, err } // DeleteObject makes a presigned request that can be used to delete an object from a bucket. func (presigner Presigner) DeleteObject(bucketName string, objectKey string) (*v4.PresignedHTTPRequest, error) { request, err := presigner.PresignClient.PresignDeleteObject(context.TODO(), &s3.DeleteObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't get a presigned request to delete object %v. Here's why: %v\n", objectKey, err) } return request, err }

Run an interactive example that generates and uses presigned URLs to upload, download, and delete an S3 object.

// RunPresigningScenario is an interactive example that shows you how to get presigned // HTTP requests that you can use to move data into and out of Amazon Simple Storage // Service (Amazon S3). The presigned requests contain temporary credentials and can // be used by an HTTP client. // // 1. Get a presigned request to put an object in a bucket. // 2. Use the net/http package to use the presigned request to upload a local file to the bucket. // 3. Get a presigned request to get an object from a bucket. // 4. Use the net/http package to use the presigned request to download the object to a local file. // 5. Get a presigned request to delete an object from a bucket. // 6. Use the net/http package to use the presigned request to delete the object. // // This example creates an Amazon S3 presign client from the specified sdkConfig so that // you can replace it with a mocked or stubbed config for unit testing. // // It uses a questioner from the `demotools` package to get input during the example. // This package can be found in the ..\..\demotools folder of this repo. // // It uses an IHttpRequester interface to abstract HTTP requests so they can be mocked // during testing. func RunPresigningScenario(sdkConfig aws.Config, questioner demotools.IQuestioner, httpRequester IHttpRequester) { defer func() { if r := recover(); r != nil { fmt.Printf("Something went wrong with the demo.") } }() log.Println(strings.Repeat("-", 88)) log.Println("Welcome to the Amazon S3 presigning demo.") log.Println(strings.Repeat("-", 88)) s3Client := s3.NewFromConfig(sdkConfig) bucketBasics := actions.BucketBasics{S3Client: s3Client} presignClient := s3.NewPresignClient(s3Client) presigner := actions.Presigner{PresignClient: presignClient} bucketName := questioner.Ask("We'll need a bucket. Enter a name for a bucket "+ "you own or one you want to create:", demotools.NotEmpty{}) bucketExists, err := bucketBasics.BucketExists(bucketName) if err != nil { panic(err) } if !bucketExists { err = bucketBasics.CreateBucket(bucketName, sdkConfig.Region) if err != nil { panic(err) } else { log.Println("Bucket created.") } } log.Println(strings.Repeat("-", 88)) log.Printf("Let's presign a request to upload a file to your bucket.") uploadFilename := questioner.Ask("Enter the path to a file you want to upload:", demotools.NotEmpty{}) uploadKey := questioner.Ask("What would you like to name the uploaded object?", demotools.NotEmpty{}) uploadFile, err := os.Open(uploadFilename) if err != nil { panic(err) } defer uploadFile.Close() presignedPutRequest, err := presigner.PutObject(bucketName, uploadKey, 60) if err != nil { panic(err) } log.Printf("Got a presigned %v request to URL:\n\t%v\n", presignedPutRequest.Method, presignedPutRequest.URL) log.Println("Using net/http to send the request...") info, err := uploadFile.Stat() if err != nil { panic(err) } putResponse, err := httpRequester.Put(presignedPutRequest.URL, info.Size(), uploadFile) if err != nil { panic(err) } log.Printf("%v object %v with presigned URL returned %v.", presignedPutRequest.Method, uploadKey, putResponse.StatusCode) log.Println(strings.Repeat("-", 88)) log.Printf("Let's presign a request to download the object.") questioner.Ask("Press Enter when you're ready.") presignedGetRequest, err := presigner.GetObject(bucketName, uploadKey, 60) if err != nil { panic(err) } log.Printf("Got a presigned %v request to URL:\n\t%v\n", presignedGetRequest.Method, presignedGetRequest.URL) log.Println("Using net/http to send the request...") getResponse, err := httpRequester.Get(presignedGetRequest.URL) if err != nil { panic(err) } log.Printf("%v object %v with presigned URL returned %v.", presignedGetRequest.Method, uploadKey, getResponse.StatusCode) defer getResponse.Body.Close() downloadBody, err := io.ReadAll(getResponse.Body) if err != nil { panic(err) } log.Printf("Downloaded %v bytes. Here are the first 100 of them:\n", len(downloadBody)) log.Println(strings.Repeat("-", 88)) log.Println(string(downloadBody[:100])) log.Println(strings.Repeat("-", 88)) log.Println("Let's presign a request to delete the object.") questioner.Ask("Press Enter when you're ready.") presignedDelRequest, err := presigner.DeleteObject(bucketName, uploadKey) if err != nil { panic(err) } log.Printf("Got a presigned %v request to URL:\n\t%v\n", presignedDelRequest.Method, presignedDelRequest.URL) log.Println("Using net/http to send the request...") delResponse, err := httpRequester.Delete(presignedDelRequest.URL) if err != nil { panic(err) } log.Printf("%v object %v with presigned URL returned %v.\n", presignedDelRequest.Method, uploadKey, delResponse.StatusCode) log.Println(strings.Repeat("-", 88)) log.Println("Thanks for watching!") log.Println(strings.Repeat("-", 88)) }

Define an HTTP request wrapper used by the example to make HTTP requests.

// IHttpRequester abstracts HTTP requests into an interface so it can be mocked during // unit testing. type IHttpRequester interface { Get(url string) (resp *http.Response, err error) Put(url string, contentLength int64, body io.Reader) (resp *http.Response, err error) Delete(url string) (resp *http.Response, err error) } // HttpRequester uses the net/http package to make HTTP requests during the scenario. type HttpRequester struct{} func (httpReq HttpRequester) Get(url string) (resp *http.Response, err error) { return http.Get(url) } func (httpReq HttpRequester) Put(url string, contentLength int64, body io.Reader) (resp *http.Response, err error) { putRequest, err := http.NewRequest("PUT", url, body) if err != nil { return nil, err } putRequest.ContentLength = contentLength return http.DefaultClient.Do(putRequest) } func (httpReq HttpRequester) Delete(url string) (resp *http.Response, err error) { delRequest, err := http.NewRequest("DELETE", url, nil) if err != nil { return nil, err } return http.DefaultClient.Do(delRequest) }

The following code example shows how to:

  • Create a bucket and upload a file to it.

  • Download an object from a bucket.

  • Copy an object to a subfolder in a bucket.

  • List the objects in a bucket.

  • Delete the bucket objects and the bucket.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

Define a struct that wraps bucket and object actions used by the scenario.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // ListBuckets lists the buckets in the current account. func (basics BucketBasics) ListBuckets() ([]types.Bucket, error) { result, err := basics.S3Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{}) var buckets []types.Bucket if err != nil { log.Printf("Couldn't list buckets for your account. Here's why: %v\n", err) } else { buckets = result.Buckets } return buckets, err } // BucketExists checks whether a bucket exists in the current account. func (basics BucketBasics) BucketExists(bucketName string) (bool, error) { _, err := basics.S3Client.HeadBucket(context.TODO(), &s3.HeadBucketInput{ Bucket: aws.String(bucketName), }) exists := true if err != nil { var apiError smithy.APIError if errors.As(err, &apiError) { switch apiError.(type) { case *types.NotFound: log.Printf("Bucket %v is available.\n", bucketName) exists = false err = nil default: log.Printf("Either you don't have access to bucket %v or another error occurred. "+ "Here's what happened: %v\n", bucketName, err) } } } else { log.Printf("Bucket %v exists and you already own it.", bucketName) } return exists, err } // CreateBucket creates a bucket with the specified name in the specified Region. func (basics BucketBasics) CreateBucket(name string, region string) error { _, err := basics.S3Client.CreateBucket(context.TODO(), &s3.CreateBucketInput{ Bucket: aws.String(name), CreateBucketConfiguration: &types.CreateBucketConfiguration{ LocationConstraint: types.BucketLocationConstraint(region), }, }) if err != nil { log.Printf("Couldn't create bucket %v in Region %v. Here's why: %v\n", name, region, err) } return err } // UploadFile reads from a file and puts the data into an object in a bucket. func (basics BucketBasics) UploadFile(bucketName string, objectKey string, fileName string) error { file, err := os.Open(fileName) if err != nil { log.Printf("Couldn't open file %v to upload. Here's why: %v\n", fileName, err) } else { defer file.Close() _, err = basics.S3Client.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), Body: file, }) if err != nil { log.Printf("Couldn't upload file %v to %v:%v. Here's why: %v\n", fileName, bucketName, objectKey, err) } } return err } // UploadLargeObject uses an upload manager to upload data to an object in a bucket. // The upload manager breaks large data into parts and uploads the parts concurrently. func (basics BucketBasics) UploadLargeObject(bucketName string, objectKey string, largeObject []byte) error { largeBuffer := bytes.NewReader(largeObject) var partMiBs int64 = 10 uploader := manager.NewUploader(basics.S3Client, func(u *manager.Uploader) { u.PartSize = partMiBs * 1024 * 1024 }) _, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), Body: largeBuffer, }) if err != nil { log.Printf("Couldn't upload large object to %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return err } // DownloadFile gets an object from a bucket and stores it in a local file. func (basics BucketBasics) DownloadFile(bucketName string, objectKey string, fileName string) error { result, err := basics.S3Client.GetObject(context.TODO(), &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't get object %v:%v. Here's why: %v\n", bucketName, objectKey, err) return err } defer result.Body.Close() file, err := os.Create(fileName) if err != nil { log.Printf("Couldn't create file %v. Here's why: %v\n", fileName, err) return err } defer file.Close() body, err := io.ReadAll(result.Body) if err != nil { log.Printf("Couldn't read object body from %v. Here's why: %v\n", objectKey, err) } _, err = file.Write(body) return err } // DownloadLargeObject uses a download manager to download an object from a bucket. // The download manager gets the data in parts and writes them to a buffer until all of // the data has been downloaded. func (basics BucketBasics) DownloadLargeObject(bucketName string, objectKey string) ([]byte, error) { var partMiBs int64 = 10 downloader := manager.NewDownloader(basics.S3Client, func(d *manager.Downloader) { d.PartSize = partMiBs * 1024 * 1024 }) buffer := manager.NewWriteAtBuffer([]byte{}) _, err := downloader.Download(context.TODO(), buffer, &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't download large object from %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return buffer.Bytes(), err } // CopyToFolder copies an object in a bucket to a subfolder in the same bucket. func (basics BucketBasics) CopyToFolder(bucketName string, objectKey string, folderName string) error { _, err := basics.S3Client.CopyObject(context.TODO(), &s3.CopyObjectInput{ Bucket: aws.String(bucketName), CopySource: aws.String(fmt.Sprintf("%v/%v", bucketName, objectKey)), Key: aws.String(fmt.Sprintf("%v/%v", folderName, objectKey)), }) if err != nil { log.Printf("Couldn't copy object from %v:%v to %v:%v/%v. Here's why: %v\n", bucketName, objectKey, bucketName, folderName, objectKey, err) } return err } // CopyToBucket copies an object in a bucket to another bucket. func (basics BucketBasics) CopyToBucket(sourceBucket string, destinationBucket string, objectKey string) error { _, err := basics.S3Client.CopyObject(context.TODO(), &s3.CopyObjectInput{ Bucket: aws.String(destinationBucket), CopySource: aws.String(fmt.Sprintf("%v/%v", sourceBucket, objectKey)), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't copy object from %v:%v to %v:%v. Here's why: %v\n", sourceBucket, objectKey, destinationBucket, objectKey, err) } return err } // ListObjects lists the objects in a bucket. func (basics BucketBasics) ListObjects(bucketName string) ([]types.Object, error) { result, err := basics.S3Client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{ Bucket: aws.String(bucketName), }) var contents []types.Object if err != nil { log.Printf("Couldn't list objects in bucket %v. Here's why: %v\n", bucketName, err) } else { contents = result.Contents } return contents, err } // DeleteObjects deletes a list of objects from a bucket. func (basics BucketBasics) DeleteObjects(bucketName string, objectKeys []string) error { var objectIds []types.ObjectIdentifier for _, key := range objectKeys { objectIds = append(objectIds, types.ObjectIdentifier{Key: aws.String(key)}) } output, err := basics.S3Client.DeleteObjects(context.TODO(), &s3.DeleteObjectsInput{ Bucket: aws.String(bucketName), Delete: &types.Delete{Objects: objectIds}, }) if err != nil { log.Printf("Couldn't delete objects from bucket %v. Here's why: %v\n", bucketName, err) } else { log.Printf("Deleted %v objects.\n", len(output.Deleted)) } return err } // DeleteBucket deletes a bucket. The bucket must be empty or an error is returned. func (basics BucketBasics) DeleteBucket(bucketName string) error { _, err := basics.S3Client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{ Bucket: aws.String(bucketName)}) if err != nil { log.Printf("Couldn't delete bucket %v. Here's why: %v\n", bucketName, err) } return err }

Run an interactive scenario that shows you how work with S3 buckets and objects.

// RunGetStartedScenario is an interactive example that shows you how to use Amazon // Simple Storage Service (Amazon S3) to create an S3 bucket and use it to store objects. // // 1. Create a bucket. // 2. Upload a local file to the bucket. // 3. Upload a large object to the bucket by using an upload manager. // 4. Download an object to a local file. // 5. Download a large object by using a download manager. // 6. Copy an object to a different folder in the bucket. // 7. List objects in the bucket. // 8. Delete all objects in the bucket. // 9. Delete the bucket. // // This example creates an Amazon S3 service client from the specified sdkConfig so that // you can replace it with a mocked or stubbed config for unit testing. // // It uses a questioner from the `demotools` package to get input during the example. // This package can be found in the ..\..\demotools folder of this repo. func RunGetStartedScenario(sdkConfig aws.Config, questioner demotools.IQuestioner) { defer func() { if r := recover(); r != nil { fmt.Println("Something went wrong with the demo.\n", r) } }() log.Println(strings.Repeat("-", 88)) log.Println("Welcome to the Amazon S3 getting started demo.") log.Println(strings.Repeat("-", 88)) s3Client := s3.NewFromConfig(sdkConfig) bucketBasics := actions.BucketBasics{S3Client: s3Client} count := 10 log.Printf("Let's list up to %v buckets for your account:", count) buckets, err := bucketBasics.ListBuckets() if err != nil { panic(err) } if len(buckets) == 0 { log.Println("You don't have any buckets!") } else { if count > len(buckets) { count = len(buckets) } for _, bucket := range buckets[:count] { log.Printf("\t%v\n", *bucket.Name) } } bucketName := questioner.Ask("Let's create a bucket. Enter a name for your bucket:", demotools.NotEmpty{}) bucketExists, err := bucketBasics.BucketExists(bucketName) if err != nil { panic(err) } if !bucketExists { err = bucketBasics.CreateBucket(bucketName, sdkConfig.Region) if err != nil { panic(err) } else { log.Println("Bucket created.") } } log.Println(strings.Repeat("-", 88)) fmt.Println("Let's upload a file to your bucket.") smallFile := questioner.Ask("Enter the path to a file you want to upload:", demotools.NotEmpty{}) const smallKey = "doc-example-key" err = bucketBasics.UploadFile(bucketName, smallKey, smallFile) if err != nil { panic(err) } log.Printf("Uploaded %v as %v.\n", smallFile, smallKey) log.Println(strings.Repeat("-", 88)) mibs := 30 log.Printf("Let's create a slice of %v MiB of random bytes and upload it to your bucket. ", mibs) questioner.Ask("Press Enter when you're ready.") largeBytes := make([]byte, 1024*1024*mibs) rand.Seed(time.Now().Unix()) rand.Read(largeBytes) largeKey := "doc-example-large" log.Println("Uploading...") err = bucketBasics.UploadLargeObject(bucketName, largeKey, largeBytes) if err != nil { panic(err) } log.Printf("Uploaded %v MiB object as %v", mibs, largeKey) log.Println(strings.Repeat("-", 88)) log.Printf("Let's download %v to a file.", smallKey) downloadFileName := questioner.Ask("Enter a name for the downloaded file:", demotools.NotEmpty{}) err = bucketBasics.DownloadFile(bucketName, smallKey, downloadFileName) if err != nil { panic(err) } log.Printf("File %v downloaded.", downloadFileName) log.Println(strings.Repeat("-", 88)) log.Printf("Let's download the %v MiB object.", mibs) questioner.Ask("Press Enter when you're ready.") log.Println("Downloading...") largeDownload, err := bucketBasics.DownloadLargeObject(bucketName, largeKey) if err != nil { panic(err) } log.Printf("Downloaded %v bytes.", len(largeDownload)) log.Println(strings.Repeat("-", 88)) log.Printf("Let's copy %v to a folder in the same bucket.", smallKey) folderName := questioner.Ask("Enter a folder name: ", demotools.NotEmpty{}) err = bucketBasics.CopyToFolder(bucketName, smallKey, folderName) if err != nil { panic(err) } log.Printf("Copied %v to %v/%v.\n", smallKey, folderName, smallKey) log.Println(strings.Repeat("-", 88)) log.Println("Let's list the objects in your bucket.") questioner.Ask("Press Enter when you're ready.") objects, err := bucketBasics.ListObjects(bucketName) if err != nil { panic(err) } log.Printf("Found %v objects.\n", len(objects)) var objKeys []string for _, object := range objects { objKeys = append(objKeys, *object.Key) log.Printf("\t%v\n", *object.Key) } log.Println(strings.Repeat("-", 88)) if questioner.AskBool("Do you want to delete your bucket and all of its "+ "contents? (y/n)", "y") { log.Println("Deleting objects.") err = bucketBasics.DeleteObjects(bucketName, objKeys) if err != nil { panic(err) } log.Println("Deleting bucket.") err = bucketBasics.DeleteBucket(bucketName) if err != nil { panic(err) } log.Printf("Deleting downloaded file %v.\n", downloadFileName) err = os.Remove(downloadFileName) if err != nil { panic(err) } } else { log.Println("Okay. Don't forget to delete objects from your bucket to avoid charges.") } log.Println(strings.Repeat("-", 88)) log.Println("Thanks for watching!") log.Println(strings.Repeat("-", 88)) }

The following code example shows how to upload or download large files to and from Amazon S3.

For more information, see Uploading an object using multipart upload.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

Upload a large object by using an upload manager to break the data into parts and upload them concurrently.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client } // UploadLargeObject uses an upload manager to upload data to an object in a bucket. // The upload manager breaks large data into parts and uploads the parts concurrently. func (basics BucketBasics) UploadLargeObject(bucketName string, objectKey string, largeObject []byte) error { largeBuffer := bytes.NewReader(largeObject) var partMiBs int64 = 10 uploader := manager.NewUploader(basics.S3Client, func(u *manager.Uploader) { u.PartSize = partMiBs * 1024 * 1024 }) _, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), Body: largeBuffer, }) if err != nil { log.Printf("Couldn't upload large object to %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return err }

Download a large object by using a download manager to get the data in parts and download them concurrently.

// DownloadLargeObject uses a download manager to download an object from a bucket. // The download manager gets the data in parts and writes them to a buffer until all of // the data has been downloaded. func (basics BucketBasics) DownloadLargeObject(bucketName string, objectKey string) ([]byte, error) { var partMiBs int64 = 10 downloader := manager.NewDownloader(basics.S3Client, func(d *manager.Downloader) { d.PartSize = partMiBs * 1024 * 1024 }) buffer := manager.NewWriteAtBuffer([]byte{}) _, err := downloader.Download(context.TODO(), buffer, &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't download large object from %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return buffer.Bytes(), err }

Serverless examples

The following code example shows how to implement a Lambda function that receives an event triggered by uploading an object to an S3 bucket. The function retrieves the S3 bucket name and object key from the event parameter and calls the Amazon S3 API to retrieve and log the content type of the object.

SDK for Go V2
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the Serverless examples repository.

Consuming an S3 event with Lambda using Go.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package main import ( "context" "log" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) func handler(ctx context.Context, s3Event events.S3Event) error { sdkConfig, err := config.LoadDefaultConfig(ctx) if err != nil { log.Printf("failed to load default config: %s", err) return err } s3Client := s3.NewFromConfig(sdkConfig) for _, record := range s3Event.Records { bucket := record.S3.Bucket.Name key := record.S3.Object.URLDecodedKey headOutput, err := s3Client.HeadObject(ctx, &s3.HeadObjectInput{ Bucket: &bucket, Key: &key, }) if err != nil { log.Printf("error getting head of object %s/%s: %s", bucket, key, err) return err } log.Printf("successfully retrieved %s/%s of type %s", bucket, key, *headOutput.ContentType) } return nil } func main() { lambda.Start(handler) }