@@ -14,10 +14,11 @@ import (
1414 "io"
1515 "log"
1616 "os"
17+ "sync"
1718 "time"
1819
1920 "github.com/aws/aws-sdk-go-v2/aws"
20- "github.com/aws/aws-sdk-go-v2/feature/s3/manager "
21+ "github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager "
2122 "github.com/aws/aws-sdk-go-v2/service/s3"
2223 "github.com/aws/aws-sdk-go-v2/service/s3/types"
2324 "github.com/aws/smithy-go"
@@ -162,15 +163,15 @@ func (basics BucketBasics) UploadFile(ctx context.Context, bucketName string, ob
162163
163164// snippet-start:[gov2.s3.Upload]
164165
165- // UploadLargeObject uses an upload manager to upload data to an object in a bucket.
166- // The upload manager breaks large data into parts and uploads the parts concurrently.
166+ // UploadLargeObject uses the S3 transfer manager to upload data to an object in a bucket.
167+ // The transfer manager breaks large data into parts and uploads the parts concurrently.
167168func (basics BucketBasics ) UploadLargeObject (ctx context.Context , bucketName string , objectKey string , largeObject []byte ) error {
168169 largeBuffer := bytes .NewReader (largeObject )
169170 var partMiBs int64 = 10
170- uploader := manager . NewUploader (basics .S3Client , func (u * manager. Uploader ) {
171- u . PartSize = partMiBs * 1024 * 1024
171+ tm := transfermanager . New (basics .S3Client , func (o * transfermanager. Options ) {
172+ o . PartSizeBytes = partMiBs * 1024 * 1024
172173 })
173- _ , err := uploader . Upload (ctx , & s3. PutObjectInput {
174+ _ , err := tm . UploadObject (ctx , & transfermanager. UploadObjectInput {
174175 Bucket : aws .String (bucketName ),
175176 Key : aws .String (objectKey ),
176177 Body : largeBuffer ,
@@ -234,18 +235,19 @@ func (basics BucketBasics) DownloadFile(ctx context.Context, bucketName string,
234235
235236// snippet-start:[gov2.s3.Download]
236237
237- // DownloadLargeObject uses a download manager to download an object from a bucket.
238- // The download manager gets the data in parts and writes them to a buffer until all of
238+ // DownloadLargeObject uses the S3 transfer manager to download an object from a bucket.
239+ // The transfer manager gets the data in parts and writes them to a buffer until all of
239240// the data has been downloaded.
240241func (basics BucketBasics ) DownloadLargeObject (ctx context.Context , bucketName string , objectKey string ) ([]byte , error ) {
241242 var partMiBs int64 = 10
242- downloader := manager . NewDownloader (basics .S3Client , func (d * manager. Downloader ) {
243- d . PartSize = partMiBs * 1024 * 1024
243+ tm := transfermanager . New (basics .S3Client , func (o * transfermanager. Options ) {
244+ o . PartSizeBytes = partMiBs * 1024 * 1024
244245 })
245- buffer := manager .NewWriteAtBuffer ([]byte {})
246- _ , err := downloader .Download (ctx , buffer , & s3.GetObjectInput {
247- Bucket : aws .String (bucketName ),
248- Key : aws .String (objectKey ),
246+ buffer := NewWriteAtBuffer ([]byte {})
247+ _ , err := tm .DownloadObject (ctx , & transfermanager.DownloadObjectInput {
248+ Bucket : aws .String (bucketName ),
249+ Key : aws .String (objectKey ),
250+ WriterAt : buffer ,
249251 })
250252 if err != nil {
251253 log .Printf ("Couldn't download large object from %v:%v. Here's why: %v\n " ,
@@ -254,6 +256,38 @@ func (basics BucketBasics) DownloadLargeObject(ctx context.Context, bucketName s
254256 return buffer .Bytes (), err
255257}
256258
259+ // WriteAtBuffer is a thread-safe in-memory io.WriterAt implementation.
260+ type WriteAtBuffer struct {
261+ buf []byte
262+ m sync.Mutex
263+ }
264+
265+ // NewWriteAtBuffer creates a new WriteAtBuffer with an initial byte slice.
266+ func NewWriteAtBuffer (buf []byte ) * WriteAtBuffer {
267+ return & WriteAtBuffer {buf : buf }
268+ }
269+
270+ // WriteAt writes len(p) bytes to the buffer starting at byte offset off.
271+ func (b * WriteAtBuffer ) WriteAt (p []byte , off int64 ) (int , error ) {
272+ b .m .Lock ()
273+ defer b .m .Unlock ()
274+ end := int (off ) + len (p )
275+ if end > len (b .buf ) {
276+ newBuf := make ([]byte , end )
277+ copy (newBuf , b .buf )
278+ b .buf = newBuf
279+ }
280+ copy (b .buf [off :], p )
281+ return len (p ), nil
282+ }
283+
284+ // Bytes returns the contents of the buffer.
285+ func (b * WriteAtBuffer ) Bytes () []byte {
286+ b .m .Lock ()
287+ defer b .m .Unlock ()
288+ return b .buf
289+ }
290+
257291// snippet-end:[gov2.s3.Download]
258292
259293// snippet-start:[gov2.s3.CopyObject]
0 commit comments