Arbeiten mit S3 und Cloud-Speichern in Rust: Die Bibliothek aws-sdk-s3
\n\nCloud-Objektspeicher wie Amazon S3 sind zum Standard für die Speicherung und Bereitstellung von Dateien, Backups und Medieninhalten geworden. Rust als systemnahe Programmiersprache bietet leistungsstarke und sichere Werkzeuge für die Integration mit diesen Diensten. Die wichtigste Bibliothek ist aws-sdk-s3 – das offizielle SDK von Amazon für Rust.
In diesem Artikel werden wir besprechen, wie man ein Projekt einrichtet, grundlegende Operationen (Hochladen, Herunterladen, Löschen) durchführt und mit S3-kompatiblen Speichern (z. B. MinIO oder Yandex Object Storage) arbeitet.
\n\nInstallation und Konfiguration
\n\nFügen Sie in Cargo.toml hinzu:
[dependencies]\naws-sdk-s3 = "1.0"\naws-config = "1.0"\ntokio = { version = "1", features = ["full"] }\n\n\nFür die Authentifizierung werden Umgebungsvariablen oder die Datei ~/.aws/credentials verwendet:
export AWS_ACCESS_KEY_ID="your_access_key"\nexport AWS_SECRET_ACCESS_KEY="your_secret_key"\nexport AWS_DEFAULT_REGION="us-east-1"\n\n\nClient-Initialisierung
\n\nErstellen wir einen asynchronen S3-Client:
\n\nuse aws_sdk_s3::Client;\nuse aws_config::load_defaults;\nuse aws_config::BehaviorVersion;\n\n#[tokio::main]\nasync fn main() {\n let config = load_defaults(BehaviorVersion::latest()).await;\n let client = Client::new(&config);\n // jetzt ist der client bereit\n}\n\n\nDatei in S3 hochladen (Upload)
\n\nZum Hochladen von Daten wird die Methode put_object verwendet. Die Daten können als Bytes oder aus einem Stream übergeben werden:
use aws_sdk_s3::primitives::ByteStream;\nuse std::path::Path;\n\nasync fn upload_file(client: &Client, bucket: &str, key: &str, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {\n let body = ByteStream::from_path(Path::new(file_path)).await?;\n \n client\n .put_object()\n .bucket(bucket)\n .key(key)\n .body(body)\n .send()\n .await?;\n \n println!("Datei {} hochgeladen in {}/{}", file_path, bucket, key);\n Ok(())\n}\n\n\nDatei herunterladen (Get Object)
\n\nUm ein Objekt abzurufen und lokal zu speichern:
\n\nuse tokio::io::AsyncWriteExt;\n\nasync fn download_file(client: &Client, bucket: &str, key: &str, dest_path: &str) -> Result<(), Box<dyn std::error::Error>> {\n let response = client\n .get_object()\n .bucket(bucket)\n .key(key)\n .send()\n .await?;\n \n let mut file = tokio::fs::File::create(dest_path).await?;\n let mut stream = response.body;\n \n while let Some(bytes) = stream.try_next().await? {\n file.write_all(&bytes).await?;\n }\n \n println!("Datei {}/{} heruntergeladen nach {}", bucket, key, dest_path);\n Ok(())\n}\n\n\nObjekte im Bucket auflisten
\n\nListe der Dateien (Schlüssel) in einem Bucket abrufen:
\n\nasync fn list_objects(client: &Client, bucket: &str) -> Result<(), Box<dyn std::error::Error>> {\n let objects = client\n .list_objects_v2()\n .bucket(bucket)\n .send()\n .await?;\n \n if let Some(contents) = objects.contents {\n for obj in contents {\n if let Some(key) = obj.key {\n println!("- {}", key);\n }\n }\n }\n Ok(())\n}\n\n\nObjekt löschen
\n\nasync fn delete_object(client: &Client, bucket: &str, key: &str) -> Result<(), Box<dyn std::error::Error>> {\n client\n .delete_object()\n .bucket(bucket)\n .key(key)\n .send()\n .await?;\n \n println!("Objekt {}/{} gelöscht", bucket, key);\n Ok(())\n}\n\n\nArbeiten mit MinIO und anderen S3-kompatiblen Speichern
\n\nUm eine Verbindung zu MinIO (lokaler S3-Emulator) oder Yandex Object Storage herzustellen, muss der Endpunkt überschrieben werden
Auch in der Bibliothek
GraphQL-Bibliothek für C++: API-Implementierung mit graphql-cpp
wiremock-rs für Rust: Vollständige Anleitung mit Beispielen
Ramsey/UUID für PHP: Komplettguide mit Beispielen