

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

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

## Amazon S3 S3-Übertragungsmanager
<a name="transfer-managers"></a>

 Die Upload- und Download-Manager von Amazon S3 können große Objekte aufteilen, sodass sie in mehreren Teilen parallel übertragen werden können. Dies macht es einfach, unterbrochene Übertragungen wieder aufzunehmen. 

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

 Der Amazon S3 S3-Upload-Manager bestimmt, ob eine Datei in kleinere Teile aufgeteilt und parallel hochgeladen werden kann. Sie können die Anzahl der parallel Uploads und die Größe der hochgeladenen Teile anpassen. 

 Das folgende Beispiel verwendet Amazon S3`Uploader`, um eine Datei hochzuladen. `Uploader`Die Verwendung ähnelt der `s3.PutObject()` Operation. 

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

#### Konfigurationsoptionen
<a name="configuration-options"></a>

 Wenn Sie eine `Uploader` Instanz mithilfe instanziieren [NewUploader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#NewUploader), können Sie verschiedene Konfigurationsoptionen angeben, um anzupassen, wie Objekte hochgeladen werden. Optionen werden überschrieben, indem Sie ein oder mehrere Argumente für angeben. `NewUploader` Sie haben u. a. folgende Möglichkeiten: 
+  `PartSize`— Gibt die Puffergröße jedes hochzuladenden Teils in Byte an. Die Mindestgröße pro Teil beträgt 5 MiB. 
+  `Concurrency`— Gibt die Anzahl der Teile an, die parallel hochgeladen werden sollen. 
+  `LeavePartsOnError`— Gibt an, ob erfolgreich hochgeladene Teile in Amazon S3 belassen werden sollen. 

 Der `Concurrency` Wert begrenzt die Anzahl gleichzeitiger Teil-Uploads, die bei einem bestimmten `Upload` Anruf durchgeführt werden können. Dies ist kein globales Limit für die Parallelität von Clients. Passen Sie die Werte `PartSize` und die `Concurrency` Konfiguration an, um die optimale Konfiguration zu finden. Beispielsweise können Systeme mit Verbindungen mit hoher Bandbreite größere Teile und mehr Uploads parallel senden. 

 Ihre Anwendung wird beispielsweise `Uploader` mit der Einstellung `Concurrency` of von konfiguriert. `5` Wenn Ihre Anwendung dann `Upload` von zwei verschiedenen Goroutinen aus aufruft, sind das Ergebnis `10` gleichzeitige Teil-Uploads (2 Goroutinen \* 5). `Concurrency` 

**Warnung**  
 Es wird erwartet, dass Ihre Anwendung die gleichzeitigen Aufrufe begrenzt, um eine Erschöpfung der Anwendungsressourcen zu verhindern. `Upload` 

 Im Folgenden finden Sie ein Beispiel für die Festlegung der Standardgröße für Bauteile bei der `Uploader` Erstellung: 

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

 Weitere Informationen zu `Uploader` und seinen Konfigurationen finden Sie unter [Uploader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Uploader) in der AWS SDK für Go API-Referenz. 

#### PutObjectInput Feld „Körper“ (io). ReadSeeker gegen io.Reader)
<a name="putobjectinput-body-field-ioreadseeker-vs-ioreader"></a>

 Das `Body` Feld der `s3.PutObjectInput` Struktur ist ein `io.Reader` Typ. Dieses Feld kann jedoch mit einem Typ gefüllt werden, der sowohl die `io.ReaderAt` Schnittstelle als auch erfüllt, um die `io.ReadSeeker` Nutzung der Anwendungsressourcen in der Host-Umgebung zu verbessern. Im folgenden Beispiel wird der Typ erstellt`ReadSeekerAt`, der beide Schnittstellen erfüllt: 

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

 Bei `io.Reader` Typen müssen die Bytes des Lesegeräts im Speicher gepuffert werden, bevor der Teil hochgeladen werden kann. Wenn Sie den `Concurrency` Wert `PartSize` oder erhöhen, `Uploader` erhöht sich der benötigte Arbeitsspeicher (RAM) für erheblich. Der benötigte Arbeitsspeicher beträgt ungefähr *`PartSize`*\* *`Concurrency`*. Wenn Sie beispielsweise 100 MB für `PartSize` und 10 für angeben`Concurrency`, sind mindestens 1 GB erforderlich. 

 Da ein `io.Reader` Typ seine Größe nicht vor dem Lesen seiner Byte bestimmen `Uploader` kann, kann nicht berechnet werden, wie viele Teile hochgeladen werden. Folglich `Uploader` kann das Amazon S3 S3-Upload-Limit von 10.000 Teilen für große Dateien erreicht werden, wenn Sie es `PartSize` zu niedrig einstellen. Wenn Sie versuchen, mehr als 10.000 Teile hochzuladen, stoppt der Upload und es wird ein Fehler zurückgegeben. 

 Bei `body` Werten, die den `ReadSeekerAt` Typ implementieren, `Uploader` puffert der den Hauptinhalt nicht im Speicher, bevor er an Amazon S3 gesendet wird. `Uploader`berechnet die erwartete Anzahl von Teilen, bevor die Datei auf Amazon S3 hochgeladen wird. Wenn der aktuelle Wert von mehr als 10.000 Teile zum Hochladen der Datei `PartSize` erfordert, wird der Wert für die Bauteilgröße `Uploader` erhöht, sodass weniger Teile benötigt werden. 

#### Umgang mit fehlgeschlagenen Uploads
<a name="handling-failed-uploads"></a>

 Wenn ein Upload zu Amazon S3 fehlschlägt, `Uploader` verwendet standardmäßig den Amazon S3 `AbortMultipartUpload` S3-Vorgang, um die hochgeladenen Teile zu entfernen. Diese Funktion stellt sicher, dass fehlgeschlagene Uploads keinen Amazon S3 S3-Speicherplatz verbrauchen. 

 Sie können `LeavePartsOnError` den Wert auf true setzen, damit die erfolgreich hochgeladenen Teile `Uploader` nicht gelöscht werden. Dies ist nützlich, um teilweise abgeschlossene Uploads wieder aufzunehmen. Um mit hochgeladenen Teilen arbeiten zu können, müssen Sie die Informationen über den `UploadID` fehlgeschlagenen Upload erhalten. Das folgende Beispiel zeigt, wie Sie den Schnittstellentyp `manager.MultiUploadFailure` Fehler verwenden, um den zu ermitteln`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
}
```

#### Uploader-Optionen pro Upload überschreiben
<a name="overriding-uploader-options-per-upload"></a>

 Sie können die `Uploader` Optionen beim Aufrufen überschreiben, `Upload` indem Sie der Methode ein oder mehrere Argumente zur Verfügung stellen. Bei diesen Überschreibungen handelt es sich um Änderungen, bei denen die Parallelität gewährleistet ist. Sie wirken sich nicht auf laufende Uploads oder nachfolgende Aufrufe an den Manager aus. `Upload` Um beispielsweise die `PartSize` Konfiguration für eine bestimmte Upload-Anfrage zu überschreiben: 

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

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

##### Einen Ordner auf Amazon S3 hochladen
<a name="upload-a-folder-to-s3"></a>

 Das folgende Beispiel verwendet das `path/filepath` Paket, um rekursiv eine Liste von Dateien zu sammeln und sie in den angegebenen Amazon S3 S3-Bucket hochzuladen. Den Schlüsseln der Amazon S3 S3-Objekte wird der relative Pfad der Datei vorangestellt. 

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

### Laden Sie den Manager herunter
<a name="download-manager"></a>

 Der Amazon S3 [Downloader-Manager](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#Downloader) bestimmt, ob eine Datei in kleinere Teile aufgeteilt und parallel heruntergeladen werden kann. Sie können die Anzahl der parallel Downloads und die Größe der heruntergeladenen Teile anpassen. 

#### Beispiel: Laden Sie eine Datei herunter
<a name="example-download-a-file"></a>

 Im folgenden Beispiel wird Amazon S3 verwendet`Downloader`, um eine Datei herunterzuladen. Die Verwendung `Downloader` ähnelt der von [S3. GetObject](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#Client.GetObject)Betrieb. 

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

 Der `downloadFile` Parameter ist ein `io.WriterAt` Typ. Die `WriterAt` Schnittstelle ermöglicht es`Downloader`, mehrere Teile der Datei parallel zu schreiben. 

#### Konfigurationsoptionen
<a name="configuration-options-1"></a>

 Wenn Sie eine `Downloader` Instanz instanziieren, können Sie Konfigurationsoptionen angeben, um anzupassen, wie Objekte heruntergeladen werden: 
+  `PartSize`— Gibt die Puffergröße jedes herunterzuladenden Teils in Byte an. Die Mindestgröße pro Teil beträgt 5 MB. 
+  `Concurrency`— Gibt die Anzahl der Teile an, die parallel heruntergeladen werden sollen. 

 Der `Concurrency` Wert begrenzt die Anzahl der gleichzeitigen Downloads von Teilen, die bei einem bestimmten `Download` Anruf ausgeführt werden können. Dies ist kein globales Limit für die Parallelität von Clients. Passen Sie die Werte `PartSize` und die `Concurrency` Konfiguration an, um die optimale Konfiguration zu finden. Beispielsweise können Systeme mit Verbindungen mit hoher Bandbreite größere Teile und mehr Downloads parallel empfangen. 

 Ihre Anwendung wird beispielsweise `Downloader` mit einem `Concurrency` von konfiguriert. `5` Ihre Anwendung ruft dann `Download` von zwei verschiedenen Goroutinen aus auf. Das Ergebnis sind `10` gleichzeitige Downloads von Teilen (2 Goroutinen \* 5). `Concurrency` 

**Warnung**  
 Es wird erwartet, dass Ihre Anwendung die Anzahl gleichzeitiger Aufrufe begrenzt, um eine Erschöpfung der Anwendungsressourcen zu verhindern`Download`. 

 Weitere Informationen zu `Downloader` und den anderen Konfigurationsoptionen finden Sie unter [Manager.Downloader](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager/#Downloader) in der API-Referenz. AWS SDK für Go 

#### Überschreiben der Downloader-Optionen pro Download
<a name="overriding-downloader-options-per-download"></a>

 Sie können die `Downloader` Optionen beim Aufrufen überschreiben, `Download` indem Sie der Methode ein oder mehrere funktionale Argumente zur Verfügung stellen. Bei diesen Überschreibungen handelt es sich um Änderungen, die gleichzeitig funktionieren und sich nicht auf laufende Uploads oder nachfolgende `Download` Aufrufe an den Manager auswirken. Um beispielsweise die `PartSize` Konfiguration für eine bestimmte Upload-Anfrage zu überschreiben: 

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

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

##### Alle Objekte in einem Bucket herunterladen
<a name="download-all-objects-in-a-bucket"></a>

 Das folgende Beispiel verwendet Paginierung, um eine Liste von Objekten aus einem Amazon S3 S3-Bucket zu sammeln. Anschließend wird jedes Objekt in eine lokale Datei heruntergeladen. 

```
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)ist eine Hilfsfunktion zur Bestimmung des Standorts der AWS Region eines Amazon S3 S3-Buckets. `GetBucketRegion`nimmt einen Amazon S3 S3-Client und verwendet ihn, um den Speicherort des angeforderten Buckets innerhalb der AWS Partition zu ermitteln, die der konfigurierten Region des Clients zugeordnet ist. 

 Um beispielsweise die Region für den Bucket zu finden`{{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)
```

 Wenn `GetBucketRegion` die Position eines Buckets nicht aufgelöst werden kann, gibt die Funktion einen [BucketNotFound](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/s3/manager#BucketNotFound)Fehlertyp zurück, wie im Beispiel gezeigt. 

## Streaming-Eingabe nicht auffindbar
<a name="unseekable-streaming-input"></a>

 Für API-Operationen wie `PutObject` und erwartet der Amazon S3 S3-Client`UploadPart`, dass der Wert des `Body` Eingabeparameters standardmäßig die [io.Seeker-Schnittstelle](https://pkg.go.dev/io#Seeker) implementiert. [Die `io.Seeker` Schnittstelle wird vom Client verwendet, um die Länge des hochzuladenden Werts zu bestimmen und den Payload-Hash für die Anforderungssignatur zu berechnen.](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) Wenn der `Body` Eingabeparameterwert nicht implementiert wird`io.Seeker`, erhält Ihre Anwendung einen Fehler. 

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

 Sie können dieses Verhalten ändern, indem Sie die Betriebsmethode [Middleware](middleware.md) mithilfe von Funktionsoptionen ändern. Der [APIOptionsWith-Helper](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#WithAPIOptions) gibt eine funktionale Option für null oder mehr Middleware-Mutatoren zurück. [Um den Client zu deaktivieren, der den Payload-Hash berechnet und die Signatur für [unsignierte Payload-Anfragen](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html) verwendet, fügen Sie v4 hinzu. 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,
))
```

**Warnung**  
 Amazon S3 erfordert, dass die Inhaltslänge für alle Objekte angegeben wird, die in einen Bucket hochgeladen wurden. Da der `Body` Eingabeparameter keine `io.Seeker` Schnittstelle implementiert, kann der Client den `ContentLength` Parameter für die Anfrage nicht berechnen. Der Parameter muss von der Anwendung bereitgestellt werden. Die Anfrage schlägt fehl, wenn der `ContentLength` Parameter nicht angegeben wird.   
 Verwenden Sie die SDKs [Amazon S3 S3-Uploadmanager](#s3-upload-manager) für Uploads, die nicht durchsuchbar sind und deren Länge nicht bekannt ist. 