

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Utilità Amazon S3
<a name="sdk-utilities-s3"></a>

## Gestori di trasferimenti Amazon S3
<a name="transfer-managers"></a>

 I gestori di upload e download di Amazon S3 possono suddividere oggetti di grandi dimensioni, in modo che possano essere trasferiti in più parti, in parallelo. In questo modo è facile riprendere i trasferimenti interrotti. 

### Gestione caricamenti Amazon S3
<a name="s3-upload-manager"></a>

 Il gestore di caricamento di Amazon S3 determina se un file può essere suddiviso in parti più piccole e caricato in parallelo. Puoi personalizzare il numero di caricamenti paralleli e la dimensione delle parti caricate. 

 L'esempio seguente utilizza Amazon S3 `Uploader` per caricare un file. L'utilizzo `Uploader` è simile all'`s3.PutObject()`operazione. 

```
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,
})
```

#### Opzioni di configurazione
<a name="configuration-options"></a>

 Quando si crea un'`Uploader`istanza utilizzando [NewUploader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#NewUploader), è possibile specificare diverse opzioni di configurazione per personalizzare il modo in cui gli oggetti vengono caricati. Le opzioni vengono sovrascritte fornendo uno o più argomenti a. `NewUploader` Le opzioni includono: 
+  `PartSize`— specifica la dimensione del buffer, in byte, di ogni parte da caricare. La dimensione minima per parte è di 5 MiB. 
+  `Concurrency`— specifica il numero di parti da caricare in parallelo. 
+  `LeavePartsOnError`— Indica se lasciare le parti caricate correttamente in Amazon S3. 

 Il `Concurrency` valore limita il numero simultaneo di caricamenti di parti che possono verificarsi per una determinata chiamata. `Upload` Non si tratta di un limite globale di concorrenza tra client. Modifica i valori `PartSize` e di `Concurrency` configurazione per trovare la configurazione ottimale. Ad esempio, i sistemi con connessioni a larghezza di banda elevata possono inviare parti più grandi e più caricamenti in parallelo. 

 Ad esempio, l'applicazione viene configurata `Uploader` con un'`Concurrency`impostazione di. `5` Se l'applicazione chiama poi `Upload` da due goroutine diverse, il risultato sono caricamenti `10` simultanei di parti (2 goroutine \* 5). `Concurrency` 

**avvertimento**  
 Si prevede che l'applicazione limiti le chiamate simultanee per evitare l'esaurimento delle risorse dell'applicazione. `Upload` 

 Di seguito è riportato un esempio per impostare la dimensione predefinita della parte durante la `Uploader` creazione: 

```
uploader := manager.NewUploader(client, func(u *Uploader) {
    u.PartSize = 10 * 1024 * 1024, // 10 MiB
})
```

 Per ulteriori informazioni `Uploader` e sulle relative configurazioni, consulta [Uploader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Uploader) nell' AWS SDK per Go API Reference. 

#### PutObjectInput Body Field (io. ReadSeeker rispetto a IO.Reader)
<a name="putobjectinput-body-field-ioreadseeker-vs-ioreader"></a>

 Il `Body` campo della `s3.PutObjectInput` struttura è un tipo. `io.Reader` Tuttavia, questo campo può essere compilato con un tipo che soddisfi sia l'interfaccia che l'`io.ReadSeeker``io.ReaderAt`interfaccia per migliorare l'utilizzo delle risorse applicative dell'ambiente host. L'esempio seguente crea il tipo `ReadSeekerAt` che soddisfa entrambe le interfacce: 

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

 Per `io.Reader` i tipi, i byte del lettore devono essere memorizzati nel buffer prima di poter caricare la parte. Quando si aumenta il `Concurrency` valore `PartSize` o, la memoria (RAM) richiesta per il valore `Uploader` aumenta in modo significativo. La memoria richiesta è di circa *`PartSize`*\* *`Concurrency`*. Ad esempio, se si specificano 100 MB per `PartSize` e 10 per`Concurrency`, è necessario almeno 1 GB. 

 Poiché un `io.Reader` tipo non può determinarne le dimensioni prima di leggerne i byte, `Uploader` non può calcolare quante parti verranno caricate. Di conseguenza, `Uploader` puoi raggiungere il limite di caricamento di Amazon S3 di 10.000 parti per file di grandi dimensioni se imposti un valore `PartSize` troppo basso. Se tenti di caricare più di 10.000 parti, il caricamento si interrompe e restituisce un errore. 

 Per `body` i valori che implementano il `ReadSeekerAt` tipo, `Uploader` non memorizza nel buffer il contenuto del corpo in memoria prima di inviarlo ad Amazon S3. `Uploader`calcola il numero previsto di parti prima di caricare il file su Amazon S3. Se il valore corrente di `PartSize` richiede più di 10.000 parti per caricare il file, `Uploader` aumenta il valore della dimensione della parte in modo che siano necessarie meno parti. 

#### Gestione dei caricamenti non riusciti
<a name="handling-failed-uploads"></a>

 Se un caricamento su Amazon S3 fallisce, per impostazione predefinita, `Uploader` utilizza l'operazione Amazon `AbortMultipartUpload` S3 per rimuovere le parti caricate. Questa funzionalità garantisce che i caricamenti non riusciti non consumino lo storage Amazon S3. 

 Puoi impostare su `LeavePartsOnError` true in modo che `Uploader` non elimini le parti caricate correttamente. Ciò è utile per riprendere i caricamenti parzialmente completati. Per operare sulle parti caricate, è necessario ottenere l'indicazione `UploadID` del caricamento non riuscito. L'esempio seguente mostra come utilizzare il tipo di interfaccia `manager.MultiUploadFailure` di errore per ottenere il`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
}
```

#### Sovrascrivere le opzioni di caricamento per caricamento
<a name="overriding-uploader-options-per-upload"></a>

 È possibile sovrascrivere le `Uploader` opzioni durante la chiamata `Upload` fornendo uno o più argomenti al metodo. Queste sostituzioni sono modifiche sicure per la concorrenza e non influiscono sui caricamenti in corso o sulle successive chiamate al gestore. `Upload` Ad esempio, per sovrascrivere la configurazione per una richiesta di caricamento specifica: `PartSize` 

```
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
})
```

#### Esempi
<a name="examples"></a>

##### Caricare una cartella su Amazon S3
<a name="upload-a-folder-to-s3"></a>

 L'esempio seguente utilizza il `path/filepath` pacchetto per raccogliere in modo ricorsivo un elenco di file e caricarli nel bucket Amazon S3 specificato. Le chiavi degli oggetti Amazon S3 sono precedute dal percorso relativo del file. 

```
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
}
```

### Download Manager
<a name="download-manager"></a>

 Il gestore di Amazon S3 [Downloader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Downloader) determina se un file può essere suddiviso in parti più piccole e scaricato in parallelo. È possibile personalizzare il numero di download paralleli e la dimensione delle parti scaricate. 

#### Esempio: scaricare un file
<a name="example-download-a-file"></a>

 L'esempio seguente utilizza Amazon S3 `Downloader` per scaricare un file. Using `Downloader` è simile a [s3. GetObject](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#Client.GetObject)operazione. 

```
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}}"),
})
```

 Il `downloadFile` parametro è un `io.WriterAt` tipo. L'`WriterAt`interfaccia consente di `Downloader` scrivere più parti del file in parallelo. 

#### Opzioni di configurazione
<a name="configuration-options-1"></a>

 Quando crei un'`Downloader`istanza, puoi specificare le opzioni di configurazione per personalizzare il modo in cui gli oggetti vengono scaricati: 
+  `PartSize`— specifica la dimensione del buffer, in byte, di ogni parte da scaricare. La dimensione minima per parte è di 5 MB. 
+  `Concurrency`— specifica il numero di parti da scaricare in parallelo. 

 Il `Concurrency` valore limita il numero simultaneo di download di parti che possono verificarsi per una determinata `Download` chiamata. Non si tratta di un limite globale di concorrenza tra client. Modifica i valori `PartSize` e di `Concurrency` configurazione per trovare la configurazione ottimale. Ad esempio, i sistemi con connessioni a larghezza di banda elevata possono ricevere parti più grandi e più download in parallelo. 

 Ad esempio, l'applicazione viene configurata `Downloader` con un di. `Concurrency` `5` L'applicazione chiama quindi `Download` da due goroutine diverse, il risultato saranno download `10` simultanei di parti (2 goroutine \* 5). `Concurrency` 

**avvertimento**  
 Si prevede che l'applicazione limiti le chiamate simultanee per evitare l'esaurimento delle risorse dell'applicazione. `Download` 

 Per ulteriori informazioni sulle `Downloader` altre opzioni di configurazione, consulta [Manager.downloader nell'](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager/#Downloader)API Reference. AWS SDK per Go 

#### Ignorare le opzioni del downloader per download
<a name="overriding-downloader-options-per-download"></a>

 È possibile sovrascrivere le `Downloader` opzioni durante la chiamata `Download` fornendo uno o più argomenti funzionali al metodo. Queste sostituzioni sono modifiche sicure dal punto di vista della concorrenza e non influiscono sui caricamenti in corso o sulle successive chiamate al gestore. `Download` Ad esempio, per sovrascrivere la `PartSize` configurazione per una richiesta di caricamento specifica: 

```
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
})
```

##### Esempi
<a name="examples-1"></a>

##### Scarica tutti gli oggetti in un secchio
<a name="download-all-objects-in-a-bucket"></a>

 L'esempio seguente utilizza la paginazione per raccogliere un elenco di oggetti da un bucket Amazon S3. Quindi scarica ogni oggetto in un file locale. 

```
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)è una funzione di utilità per determinare la posizione AWS della regione di un bucket Amazon S3. `GetBucketRegion`prende un client Amazon S3 e lo utilizza per determinare la posizione del bucket richiesto all'interno della AWS partizione associata alla regione configurata del client. 

 Ad esempio, per trovare la regione per il 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 non `GetBucketRegion` è in grado di risolvere la posizione di un Bucket, la funzione restituisce un tipo di [BucketNotFound](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#BucketNotFound)errore come mostrato nell'esempio. 

## Input di streaming non ricercabile
<a name="unseekable-streaming-input"></a>

 Per operazioni API come `PutObject` and`UploadPart`, il client Amazon S3 si aspetta che il valore del parametro di `Body` input implementi l'interfaccia [IO.Seeker](https://pkg.go.dev/io#Seeker) per impostazione predefinita. [L'`io.Seeker`interfaccia viene utilizzata dal client per determinare la lunghezza del valore da caricare e per calcolare l'hash del payload per la firma della richiesta.](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) Se il valore del parametro `Body` di input non viene implementato`io.Seeker`, l'applicazione riceverà un errore. 

```
operation error S3: PutObject, failed to compute payload hash: failed to seek
body to start, request stream is not seekable
```

 È possibile modificare questo comportamento modificando il metodo operativo [Middleware](middleware.md) utilizzando le opzioni funzionali. L'APIOptionshelper [With](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#WithAPIOptions) restituisce un'opzione funzionale per zero o più mutatori del middleware. [Per disabilitare il client che calcola l'hash del payload e utilizzare [Unsigned](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html) Payload, richiedi la firma aggiungi 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,
))
```

**avvertimento**  
 Amazon S3 richiede che venga fornita la lunghezza del contenuto per tutti gli oggetti caricati in un bucket. Poiché il parametro `Body` di input non implementa l'`io.Seeker`interfaccia, il client non sarà in grado di calcolare il `ContentLength` parametro per la richiesta. Il parametro deve essere fornito dall'applicazione. La richiesta avrà esito negativo se il `ContentLength` parametro non viene fornito.   
 Utilizza gli SDK [Gestione caricamenti Amazon S3](#s3-upload-manager) per i caricamenti che non sono ricercabili e che non hanno una lunghezza nota. 