As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Utilitários do Amazon S3
Gerentes de transferência do Amazon S3
Os gerenciadores de upload e download do Amazon S3 podem dividir objetos grandes, para que possam ser transferidos em várias partes, paralelamente. Isso facilita a retomada das transferências interrompidas.
Gerenciador de upload do Amazon S3
O gerenciador de upload do Amazon S3 determina se um arquivo pode ser dividido em partes menores e carregado paralelamente. Você pode personalizar o número de carregamentos paralelos e o tamanho das partes enviadas.
O exemplo a seguir usa o Amazon S3 Uploader
para carregar um arquivo. Uploader
O uso é semelhante à s3.PutObject()
operação.
import "context" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" import "github.com/aws/aws-sdk-go-v2/feature/s3/manager" // ... cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Printf("error: %v", err) return } client := s3.NewFromConfig(cfg) uploader := manager.NewUploader(client) result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String("
amzn-s3-demo-bucket
"), Key: aws.String("my-object-key
"), Body: uploadFile, })
Opções de configuração
Ao instanciar uma Uploader
instância usando NewUploaderNewUploader
Essas opções incluem:
-
PartSize
— Especifica o tamanho do buffer, em bytes, de cada peça a ser carregada. O tamanho mínimo por peça é de 5 MiB. -
Concurrency
— Especifica o número de peças a serem carregadas em paralelo. -
LeavePartsOnError
— Indica se as peças enviadas com sucesso devem ser deixadas no Amazon S3.
O Concurrency
valor limita o número simultâneo de carregamentos de peças que podem ocorrer em uma determinada Upload
chamada. Esse não é um limite global de simultaneidade de clientes. Ajuste os valores Concurrency
de configuração PartSize
e para encontrar a configuração ideal. Por exemplo, sistemas com conexões de alta largura de banda podem enviar peças maiores e mais carregamentos em paralelo.
Por exemplo, seu aplicativo é configurado Uploader
com uma configuração Concurrency
de5
. Se seu aplicativo então chamar Upload
de duas goroutines diferentes, o resultado serão uploads de peças 10
simultâneos (2 goroutines * 5). Concurrency
Atenção
Espera-se que seu aplicativo limite as chamadas simultâneas Upload
para evitar o esgotamento dos recursos do aplicativo.
Abaixo está um exemplo para definir o tamanho padrão da peça durante a Uploader
criação:
uploader := manager.NewUploader(client, func(u *Uploader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })
Para obter mais informações Uploader
e suas configurações, consulte Uploader na Referência
PutObjectInput Campo corporal (io. ReadSeeker versus io.Reader)
O Body
campo da s3.PutObjectInput
estrutura é um io.Reader
tipo. No entanto, esse campo pode ser preenchido com um tipo que satisfaça tanto a io.ReaderAt
interface io.ReadSeeker
quanto a fim de melhorar a utilização dos recursos do aplicativo no ambiente host. O exemplo a seguir cria o tipo ReadSeekerAt
que satisfaz as duas interfaces:
type ReadSeekerAt interface { io.ReadSeeker io.ReaderAt }
Para io.Reader
tipos, os bytes do leitor devem ser armazenados em buffer na memória antes que a peça possa ser carregada. Quando você aumenta o Concurrency
valor de PartSize
or, a memória (RAM) necessária para o Uploader
aumenta significativamente. A memória necessária é de aproximadamente PartSize
* Concurrency
. Por exemplo, especificar 100 MB para PartSize
e 10 paraConcurrency
, requer pelo menos 1 GB.
Como um io.Reader
tipo não pode determinar seu tamanho antes de ler seus bytes, Uploader
não é possível calcular quantas partes serão carregadas. Consequentemente, Uploader
pode atingir o limite de upload do Amazon S3 de 10.000 partes para arquivos grandes se você definir um valor PartSize
muito baixo. Se você tentar carregar mais de 10.000 peças, o upload será interrompido e retornará um erro.
Para body
valores que implementam o ReadSeekerAt
tipo, o Uploader
não armazena o conteúdo do corpo na memória antes de enviá-lo para o Amazon S3. Uploader
calcula o número esperado de peças antes de fazer o upload do arquivo para o Amazon S3. Se o valor atual de PartSize
exigir mais de 10.000 peças para carregar o arquivo, Uploader
aumente o valor do tamanho da peça para que menos peças sejam necessárias.
Tratamento de uploads com falha
Se um upload para o Amazon S3 falhar, por padrão, Uploader
usa a operação do Amazon AbortMultipartUpload
S3 para remover as partes carregadas. Essa funcionalidade garante que os uploads com falha não consumam o armazenamento do Amazon S3.
Você pode definir como verdadeiro LeavePartsOnError
para que Uploader
não exclua as partes enviadas com sucesso. Isso é útil para retomar carregamentos parcialmente concluídos. Para operar com peças carregadas, você deve obter o UploadID
do upload que falhou. O exemplo a seguir demonstra como usar o tipo manager.MultiUploadFailure
de interface de erro para obter o. UploadID
result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String("
amzn-s3-demo-bucket
"), Key: aws.String("my-object-key
"), Body: uploadFile, }) output, err := u.upload(input) if err != nil { var mu manager.MultiUploadFailure if errors.As(err, &mu) { // Process error and its associated uploadID fmt.Println("Error:", mu) _ = mu.UploadID() // retrieve the associated UploadID } else { // Process error generically fmt.Println("Error:", err.Error()) } return }
Substituindo as opções do carregador por upload
Você pode substituir as Uploader
opções ao chamar Upload
fornecendo um ou mais argumentos para o método. Essas substituições são modificações seguras para a concorrência e não afetam os uploads em andamento ou as chamadas subsequentes para o gerente. Upload
Por exemplo, para substituir a PartSize
configuração de uma solicitação de upload específica:
params := &s3.PutObjectInput{ Bucket: aws.String("
amzn-s3-demo-bucket
"), Key: aws.String("my-key
"), Body: myBody, } resp, err := uploader.Upload(context.TODO(), params, func(u *manager.Uploader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })
Exemplos
Faça upload de uma pasta para o Amazon S3
O exemplo a seguir usa o path/filepath
pacote para reunir recursivamente uma lista de arquivos e carregá-los no bucket do Amazon S3 especificado. As chaves dos objetos do Amazon S3 são prefixadas com o caminho relativo do arquivo.
package main import ( "context" "log" "os" "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" ) var ( localPath string bucket string prefix string ) func init() { if len(os.Args) != 4 { log.Fatalln("Usage:", os.Args[0], "<local path> <bucket> <prefix>") } localPath = os.Args[1] bucket = os.Args[2] prefix = os.Args[3] } func main() { walker := make(fileWalk) go func() { // Gather the files to upload by walking the path recursively if err := filepath.Walk(localPath, walker.Walk); err != nil { log.Fatalln("Walk failed:", err) } close(walker) }() cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalln("error:", err) } // For each file found walking, upload it to Amazon S3 uploader := manager.NewUploader(s3.NewFromConfig(cfg)) for path := range walker { rel, err := filepath.Rel(localPath, path) if err != nil { log.Fatalln("Unable to get relative path:", path, err) } file, err := os.Open(path) if err != nil { log.Println("Failed opening file", path, err) continue } defer file.Close() result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: &bucket, Key: aws.String(filepath.Join(prefix, rel)), Body: file, }) if err != nil { log.Fatalln("Failed to upload", path, err) } log.Println("Uploaded", path, result.Location) } } type fileWalk chan string func (f fileWalk) Walk(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() { f <- path } return nil }
Gerenciador de downloads
O gerenciador do Amazon S3 Downloader
Exemplo: Baixar um arquivo
O exemplo a seguir usa o Amazon S3 Downloader
para baixar um arquivo. Downloader
O uso é semelhante ao s3. GetObject
import "context" import "github.com/aws/aws-sdk-go-v2/aws" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" import "github.com/aws/aws-sdk-go-v2/feature/s3/manager" // ... cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Println("error:", err) return } client := s3.NewFromConfig(cfg) downloader := manager.NewDownloader(client) numBytes, err := downloader.Download(context.TODO(), downloadFile, &s3.GetObjectInput{ Bucket: aws.String("
amzn-s3-demo-bucket
"), Key: aws.String("my-key
"), })
O downloadFile
parâmetro é um io.WriterAt
tipo. A WriterAt
interface permite Downloader
gravar várias partes do arquivo em paralelo.
Opções de configuração
Ao instanciar uma Downloader
instância, você pode especificar opções de configuração para personalizar como os objetos são baixados:
-
PartSize
— Especifica o tamanho do buffer, em bytes, de cada parte a ser baixada. O tamanho mínimo por peça é de 5 MB. -
Concurrency
— Especifica o número de peças a serem baixadas paralelamente.
O Concurrency
valor limita o número simultâneo de downloads de peças que podem ocorrer em uma determinada Download
chamada. Esse não é um limite global de simultaneidade de clientes. Ajuste os valores Concurrency
de configuração PartSize
e para encontrar a configuração ideal. Por exemplo, sistemas com conexões de alta largura de banda podem receber peças maiores e mais downloads em paralelo.
Por exemplo, seu aplicativo é configurado Downloader
com um Concurrency
de5
. Seu aplicativo então chama Download
de duas goroutines diferentes, o resultado será downloads 10
simultâneos de partes (2 goroutines * 5). Concurrency
Atenção
Espera-se que seu aplicativo limite as chamadas simultâneas Download
para evitar o esgotamento dos recursos do aplicativo.
Para obter mais informações sobre Downloader
suas outras opções de configuração, consulte Manager.downloader
Substituindo as opções do downloader por download
Você pode substituir as Downloader
opções ao chamar Download
fornecendo um ou mais argumentos funcionais para o método. Essas substituições são modificações simultâneas seguras e não afetam os uploads em andamento ou as Download
chamadas subsequentes para o gerente. Por exemplo, para substituir a PartSize
configuração de uma solicitação de upload específica:
params := &s3.GetObjectInput{ Bucket: aws.String("
amzn-s3-demo-bucket
"), Key: aws.String("my-key
"), } resp, err := downloader.Download(context.TODO(), targetWriter, params, func(u *manager.Downloader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })
Exemplos
Baixe todos os objetos em um bucket
O exemplo a seguir usa paginação para reunir uma lista de objetos de um bucket do Amazon S3. Em seguida, ele baixa cada objeto em um arquivo local.
package main import ( "context" "fmt" "log" "os" "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" ) var ( Bucket = "
amzn-s3-demo-bucket
" // Download from this bucket Prefix = "logs/" // Using this key prefix LocalDirectory = "s3logs" // Into this directory ) func main() { cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalln("error:", err) } client := s3.NewFromConfig(cfg) manager := manager.NewDownloader(client) paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{ Bucket: &Bucket, Prefix: &Prefix, }) for paginator.HasMorePages() { page, err := paginator.NextPage(context.TODO()) if err != nil { log.Fatalln("error:", err) } for _, obj := range page.Contents { if err := downloadToFile(manager, LocalDirectory, Bucket, aws.ToString(obj.Key)); err != nil { log.Fatalln("error:", err) } } } } func downloadToFile(downloader *manager.Downloader, targetDirectory, bucket, key string) error { // Create the directories in the path file := filepath.Join(targetDirectory, key) if err := os.MkdirAll(filepath.Dir(file), 0775); err != nil { return err } // Set up the local file fd, err := os.Create(file) if err != nil { return err } defer fd.Close() // Download the file using the AWS SDK for Go fmt.Printf("Downloading s3://%s/%s to %s...\n", bucket, key, file) _, err = downloader.Download(context.TODO(), fd, &s3.GetObjectInput{Bucket: &bucket, Key: &key}) return err }
GetBucketRegion
GetBucketRegionGetBucketRegion
pega um cliente Amazon S3 e o usa para determinar a localização do bucket solicitado na AWS partição associada à região configurada do cliente.
Por exemplo, para encontrar a região do bucket
: amzn-s3-demo-bucket
cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Println("error:", err) return } bucket := "
amzn-s3-demo-bucket
" region, err := manager.GetBucketRegion(ctx, s3.NewFromConfig(cfg), bucket) if err != nil { var bnf manager.BucketNotFound if errors.As(err, &bnf) { log.Printf("unable to find bucket %s's Region\n", bucket) } else { log.Println("error:", err) } return } fmt.Printf("Bucket %s is in %s region\n", bucket, region)
Se não GetBucketRegion
for possível resolver a localização de um Bucket, a função retornará um tipo de BucketNotFound
Entrada de streaming inexplorável
Para operações de API como PutObject
eUploadPart
, o cliente Amazon S3 espera que o valor do parâmetro de Body
entrada implemente a interface IO.Seekerio.Seeker
interface é usada pelo cliente para determinar o tamanho do valor a ser carregado e para calcular o hash da carga útil para a assinatura da solicitação. Se o valor do parâmetro de Body
entrada não for implementadoio.Seeker
, seu aplicativo receberá um erro.
operation error S3: PutObject, failed to compute payload hash: failed to seek body to start, request stream is not seekable
Você pode alterar esse comportamento modificando o método de operação Middleware usando opções funcionais. O APIOptions auxiliar With
resp, err := client.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: &bucketName, Key: &objectName, Body: bytes.NewBuffer([]byte(`example object!`)), ContentLength: 15, // length of body }, s3.WithAPIOptions( v4.SwapComputePayloadSHA256ForUnsignedPayloadMiddleware, ))
Atenção
O Amazon S3 exige que o tamanho do conteúdo seja fornecido para todos os objetos carregados em um bucket. Como o parâmetro Body
de entrada não implementa a io.Seeker
interface, o cliente não poderá calcular o ContentLength
parâmetro para a solicitação. O parâmetro deve ser fornecido pelo aplicativo. A solicitação falhará se o ContentLength
parâmetro não for fornecido.
Use os SDKs Gerenciador de upload do Amazon S3 para uploads que não possam ser pesquisados e não tenham um tamanho conhecido.