

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
<a name="sdk-utilities-s3"></a>

## Gerenciadores de transferências do Amazon S3
<a name="transfer-managers"></a>

 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 de transferências interrompidas. 

### Gerenciador de uploads do Amazon S3
<a name="s3-upload-manager"></a>

 O gerenciador de uploads do Amazon S3 determina se um arquivo pode ser dividido em partes menores e carregado paralelamente. Você pode personalizar o número de uploads paralelos e o tamanho das partes enviadas. 

 O seguinte exemplo usa o `Uploader` do Amazon S3 para fazer upload de um arquivo. O uso de `Uploader` é semelhante à operação `s3.PutObject()`. 

```
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
<a name="configuration-options"></a>

 Ao instanciar uma `Uploader` instância usando [NewUploader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#NewUploader), você pode especificar várias opções de configuração para personalizar como os objetos são carregados. As opções são substituídas fornecendo um ou mais argumentos para `NewUploader`. Essas opções incluem: 
+  `PartSize`: especifica o tamanho do buffer, em bytes, de cada parte a ser carregada. O tamanho mínimo por parte é de 5 MiB. 
+  `Concurrency`: especifica o número exato de partes a serem carregadas em paralelo. 
+  `LeavePartsOnError`: indica se as partes carregadas com sucesso devem ser deixadas no Amazon S3. 

 O valor de `Concurrency` limita o número simultâneo de uploads de partes que podem ocorrer em determinada chamada de `Upload`. Esse não é um limite global de simultaneidade de clientes. Ajuste os valores de configuração `PartSize` e `Concurrency` para encontrar a configuração ideal. Por exemplo, sistemas com conexões de alta largura de banda podem enviar partes maiores e mais uploads em paralelo. 

 Por exemplo, a aplicação configura `Uploader` com `Concurrency` definida como `5`. Se a aplicação então chamar `Upload` de duas goroutines diferentes, o resultado será `10` uploads de partes simultâneos (2 goroutines \$1 5 `Concurrency`). 

**Atenção**  
 Espera-se que a aplicação limite as chamadas simultâneas para `Upload` a fim de evitar o esgotamento dos recursos da aplicação. 

 Veja a seguir um exemplo para definir o tamanho padrão da parte durante a criação de `Uploader`: 

```
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](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Uploader) da AWS SDK para Go API. 

#### PutObjectInput Campo corporal (io. ReadSeeker versus io.Reader)
<a name="putobjectinput-body-field-ioreadseeker-vs-ioreader"></a>

 O campo `Body` da estrutura `s3.PutObjectInput` é um tipo `io.Reader`. No entanto, esse campo pode ser preenchido com um tipo que satisfaça tanto a interface `io.ReadSeeker` quanto `io.ReaderAt` a fim de melhorar a utilização dos recursos da aplicação no ambiente de host. O exemplo a seguir cria o tipo `ReadSeekerAt` que satisfaz as duas interfaces: 

```
type ReadSeekerAt interface {
    io.ReadSeeker
    io.ReaderAt
}
```

 Para tipos `io.Reader`, os bytes do leitor devem ser armazenados em buffer na memória antes de fazer upload da parte. Quando você aumenta o valor de `PartSize` ou `Concurrency`, a memória (RAM) necessária para `Uploader` aumenta significativamente. A memória necessária é de aproximadamente *`PartSize`* \$1 *`Concurrency`*. Por exemplo, especificar 100 MB para `PartSize` e 10 para `Concurrency`, requer pelo menos 1 GB. 

 Como um tipo `io.Reader` não pode determinar seu tamanho antes de ler seus bytes, `Uploader` não consegue calcular quantas partes serão carregadas. Consequentemente, `Uploader` pode atingir o limite de upload do Amazon S3 de 10 mil partes para arquivos grandes caso você defina `PartSize` muito baixo. Se você tentar fazer upload de mais de 10 mil peças, o upload será interrompido e retornará um erro. 

 Para valores `body` que implementam o tipo `Uploader`, o `Uploader` não armazena o conteúdo do corpo na memória antes de enviá-lo ao Amazon S3. `ReadSeekerAt` calcula o número esperado de partes antes de fazer upload de cada arquivo no Amazon S3. Se o valor atual de `PartSize` exigir mais de 10 mil partes para fazer upload do arquivo, `Uploader` aumenta o valor do tamanho da parte para que menos partes sejam necessárias. 

#### Como gerenciar uploads com falha
<a name="handling-failed-uploads"></a>

 Se um upload para o Amazon S3 falhar, por padrão, `Uploader` usa a operação `AbortMultipartUpload` do Amazon 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 `LeavePartsOnError` como verdadeiro para que `Uploader` não exclua as partes enviadas com sucesso. Isso é útil para retomar uploads parcialmente concluídos. Para operar com partes carregadas, você deve obter o `UploadID` do upload que falhou. O exemplo a seguir demonstra como usar o tipo de interface de erro `manager.MultiUploadFailure` 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
}
```

#### Substituir as opções do uploader por upload
<a name="overriding-uploader-options-per-upload"></a>

 Você pode substituir as opções do `Uploader` ao chamar `Upload` fornecendo um ou mais argumentos para o método. Essas substituições são modificações seguras para a simultaneidade e não afetam os uploads em andamento nem as chamadas subsequentes de `Upload` ao gerenciador. Por exemplo, para substituir a configuração `PartSize` 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
<a name="examples"></a>

##### Fazer upload de uma pasta no Amazon S3
<a name="upload-a-folder-to-s3"></a>

 O exemplo a seguir usa o pacote `path/filepath` para reunir recursivamente uma lista de arquivos e fazer upload deles no bucket do Amazon S3. As chaves dos objetos do Amazon S3 têm como prefixo 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
<a name="download-manager"></a>

 O gerenciador de [downloads](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Downloader) do Amazon S3 determina se um arquivo pode ser dividido em partes menores e baixado paralelamente. Você pode personalizar o número de downloads paralelos e o tamanho das partes baixadas. 

#### Exemplo: baixar um arquivo
<a name="example-download-a-file"></a>

 O seguinte exemplo usa o `Downloader` do Amazon S3 para baixar um arquivo. `Downloader`O uso é semelhante ao [s3. GetObject](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#Client.GetObject)operação. 

```
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 parâmetro `downloadFile` é um tipo `io.WriterAt`. A interface `WriterAt` permite que o `Downloader` grave várias partes do arquivo em paralelo. 

#### Opções de configuração
<a name="configuration-options-1"></a>

 Ao instanciar uma instância `Downloader`, 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 parte é de 5 MB. 
+  `Concurrency`: especifica o número exato de partes a serem baixadas em paralelo. 

 O valor de `Concurrency` limita o número simultâneo de downloads de partes que podem ocorrer em determinada chamada de `Download`. Esse não é um limite global de simultaneidade de clientes. Ajuste os valores de configuração `PartSize` e `Concurrency` para encontrar a configuração ideal. Por exemplo, sistemas com conexões de alta largura de banda podem receber partes maiores e mais downloads em paralelo. 

 Por exemplo, a aplicação configura `Downloader` com `Concurrency` de `5`. Como a aplicação chama `Download` de duas goroutines diferentes, o resultado será `10` downloads de partes simultâneos (2 goroutines \$1 5 `Concurrency`). 

**Atenção**  
 Espera-se que a aplicação limite as chamadas simultâneas para `Download` a fim de evitar o esgotamento dos recursos da aplicação. 

 Para obter mais informações sobre `Downloader` suas outras opções de configuração, consulte [Manager.downloader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager/#Downloader) na Referência da API. AWS SDK para Go 

#### Substituir as opções do downloader por download
<a name="overriding-downloader-options-per-download"></a>

 Você pode substituir as opções do `Downloader` ao chamar `Download` fornecendo um ou mais argumentos funcionais para o método. Essas substituições são modificações seguras para a simultaneidade e não afetam os uploads em andamento nem as chamadas subsequentes de `Download` ao gerenciador. Por exemplo, para substituir a configuração `PartSize` 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
<a name="examples-1"></a>

##### Baixar todos os objetos em um bucket
<a name="download-all-objects-in-a-bucket"></a>

 O exemplo a seguir usa paginação para reunir uma lista de objetos de um bucket do Amazon S3. Depois, 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
<a name="getbucketregion"></a>

 [GetBucketRegion](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#GetBucketRegion)é uma função utilitária para determinar a localização AWS da região de um bucket do Amazon S3. `GetBucketRegion`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](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#BucketNotFound)erro, conforme mostrado no exemplo. 

## Entrada de streaming não posicionável
<a name="unseekable-streaming-input"></a>

 Para operações de API como `PutObject` e `UploadPart`, o cliente do Amazon S3 espera que o valor do parâmetro de entrada `Body` implemente a interface [io.Seeker](https://pkg.go.dev/io#Seeker) por padrão. A interface `io.Seeker` é 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](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). Se o valor do parâmetro de entrada `Body` não implementar `io.Seeker`, a aplicação 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 [Middleware](middleware.md) do método da operação usando opções funcionais. O APIOptions auxiliar [With](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#WithAPIOptions) retorna uma opção funcional para zero ou mais mutadores de middleware. [Para desativar o cliente computando o hash da carga útil e usar a assinatura de solicitação de [carga não assinada](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html), adicione v4. SwapComputePayloadSHA256ForUnsignedPayloadMiddleware](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#SwapComputePayloadSHA256ForUnsignedPayloadMiddleware). 

```
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 de entrada `Body` não implementa a interface `io.Seeker`, o cliente não pode calcular o parâmetro `ContentLength` para a solicitação. O parâmetro deve ser fornecido pela aplicação. A solicitação falhará se o parâmetro `ContentLength` não for fornecido.   
 Use os [Gerenciador de uploads do Amazon S3](#s3-upload-manager) do SDK para uploads que não são posicionáveis e não possuem um tamanho conhecido. 