Dateien zu DigitalOcean Spaces mit .NET (C#) exportieren
Exportieren Sie lokale Dateien mit dem quelloffenen AWS SDK in einen bestehenden DigitalOcean Space. Dieses Tutorial enthält ein vollständiges .NET-10-Programm für Dateien bis zu 64 MiB.
S3-Kompatibilität von DigitalOcean Spaces verstehen
Spaces unterstützt eine Teilmenge der S3-API. Konfigurieren Sie den regionalen Endpunkt und die Signaturregion explizit. Anfragen im Pfadstil und mit virtuellem Host werden unterstützt; dieses Beispiel verwendet den Pfadstil.
Erforderliche NuGet-Pakete installieren
Installieren Sie das .NET 10 SDK und führen Sie anschließend Folgendes aus:
dotnet new console --framework net10.0 --name SpacesExport
cd SpacesExport
dotnet add package AWSSDK.Core --version 4.0.102.6
dotnet add package AWSSDK.S3 --version 4.0.103.3
AWS SDK for .NET mit DigitalOcean Spaces verwenden
Legen Sie die folgenden Umgebungsvariablen in Ihrer Shell oder Ihrer Zugangsdatenverwaltung fest:
| Variable | Wert |
|---|---|
SPACES_ENDPOINT | Regionaler Endpunkt, etwa https://nyc3.digitaloceanspaces.com |
SPACES_REGION | Passende Region, etwa nyc3 |
SPACES_BUCKET | Name des bestehenden Space |
SPACES_KEY_ID | Spaces-Zugriffsschlüssel |
SPACES_APPLICATION_KEY | Geheimer Spaces-Schlüssel |
Ersetzen Sie Program.cs durch den folgenden Code. Die
SDK-Anleitung von DigitalOcean beschreibt die Konfiguration des
Endpunkts. Übergeben Sie Objektschlüssel als einfache Zeichenfolgen, auch mit Leerzeichen oder
Unicode-Zeichen; das SDK übernimmt die URL-Codierung und Signature V4.
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
public static class SpacesExporter
{
public static async Task<int> Main(string[] args)
{
using var deadline = new CancellationTokenSource(TimeSpan.FromMinutes(5));
Console.CancelKeyPress += (_, e) => { e.Cancel = true; deadline.Cancel(); };
try
{
if (args.Length != 2) throw new ArgumentException("Pass a local file and an object key.");
var endpoint = new Uri(Required("SPACES_ENDPOINT"));
if (endpoint.Scheme != "https" || endpoint.UserInfo.Length != 0 ||
endpoint.AbsolutePath != "/" || endpoint.Query.Length != 0 || endpoint.Fragment.Length != 0)
throw new ArgumentException("Use the HTTPS regional endpoint without a bucket or path.");
var config = new AmazonS3Config
{
ServiceURL = endpoint.AbsoluteUri,
AuthenticationRegion = Required("SPACES_REGION"),
ForcePathStyle = true,
MaxErrorRetry = 2,
RequestChecksumCalculation = RequestChecksumCalculation.WHEN_REQUIRED,
ResponseChecksumValidation = ResponseChecksumValidation.WHEN_REQUIRED
};
using var client = new AmazonS3Client(
Required("SPACES_KEY_ID"), Required("SPACES_APPLICATION_KEY"), config);
await UploadAsync(client, Required("SPACES_BUCKET"), args[0], args[1], deadline.Token);
Console.WriteLine("Uploaded.");
return 0;
}
catch (OperationCanceledException) { Console.Error.WriteLine("Upload canceled or timed out."); }
catch (AmazonS3Exception error) { Console.Error.WriteLine($"Storage returned HTTP {(int)error.StatusCode}."); }
catch (Exception) { Console.Error.WriteLine("Upload failed. Check the file and storage configuration."); }
return 1;
}
private static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new ArgumentException($"Missing {name}.");
public static async Task UploadAsync(IAmazonS3 client, string bucket, string path,
string key, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(key)) throw new ArgumentException("An object key is required.");
await using var input = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
if (input.Length > 64L * 1024 * 1024) throw new IOException("This example accepts at most 64 MiB.");
await client.PutObjectAsync(new PutObjectRequest
{
BucketName = bucket,
Key = key,
InputStream = input,
AutoCloseStream = false,
ContentType = "application/octet-stream",
UseChunkEncoding = false
}, cancellationToken);
}
}
Erstellen Sie eine Eingabedatei und starten Sie das Programm im Projektverzeichnis:
printf 'example export\n' > report.txt
dotnet run -- report.txt 'reports/report #1.txt'
Wiederholungslogik und Fehlerbehandlung ergänzen
Das SDK führt bei wiederholbaren Fehlern bis zu zwei Retries aus. Sowohl das Zeitlimit von fünf Minuten als auch Ctrl+C brechen die Retries und den Upload ab. Bei dauerhaften Autorisierungsfehlern endet das Programm mit einem Exitcode ungleich null, ohne Zugangsdaten oder Antwortinhalte des Dienstes offenzulegen. Prüfen Sie nach einem Netzwerkfehler mit ungewissem Ausgang das entfernte Objekt, bevor Sie einen Vorgang wiederholen, bei dem das Ersetzungsverhalten relevant ist.
Leistung mit mehrteiligen Uploads und Streaming optimieren
Das Programm streamt einen einzelnen PUT aus einer geöffneten Datei und begrenzt die Dateigröße
auf Anwendungsebene auf 64 MiB. Es führt keine mehrteiligen Uploads aus. Lassen Sie die Datei während
des Uploads unverändert. Verwenden Sie für größere Dateien die Komponente
TransferUtility des AWS SDK und sorgen Sie dafür, dass unvollständige mehrteilige
Uploads bereinigt werden; siehe die AWS-Transferdokumentation.
Dateistream und Client werden auch dann freigegeben, wenn eine Anfrage fehlschlägt. Verwenden Sie in einer dauerhaft laufenden Anwendung denselben Client für mehrere Uploads und begrenzen Sie parallele Vorgänge entsprechend den verfügbaren Speicher- und Netzwerkressourcen.
Zugriffsschlüssel und Berechtigungen sicher verwalten
Verwenden Sie einen Spaces-Schlüssel, dessen Berechtigungsumfang auf den Ziel-Bucket beschränkt ist. Das Beispiel übergibt Zugangsdaten explizit, verwendet HTTPS und belässt das Objekt standardmäßig privat. Es ändert weder die Bucket-Richtlinie noch ACLs.
Ansätze vergleichen
Das AWS SDK übernimmt Signierung, Objektschlüsselcodierung, Antwortfehler und Retries mit einer
einzigen Abhängigkeit. Eine Speicherabstraktion ist sinnvoll, wenn eine Anwendung bereits mehrere
Anbieter nutzt. Eine direkte Integration mit HttpClient erfordert eine
vollständige Implementierung von Signature V4; mit dem SDK entfällt deren Pflege im Anwendungscode.
Browser-Uploads benötigen einen separaten Ablauf: Stellen Sie in Ihrem Backend eine kurzlebige, vorsignierte URL aus und konfigurieren Sie die CORS-Richtlinie des Space für den Ursprung der Browseranfrage. Bewahren Sie den geheimen Schlüssel auf dem Server auf.
Häufige Probleme beheben
Prüfen Sie bei HTTP 403 den Zugriffsschlüssel, den geheimen Schlüssel, die Bucket-Berechtigungen,
den Endpunkt und die Signaturregion. Fehlt ein Bucket, erstellen Sie zuerst den Space oder
korrigieren Sie SPACES_BUCKET. Überschreitet eine Datei das Limit dieses Beispiels,
wechseln Sie zu einem gezielt dafür ausgelegten Ablauf mit mehrteiligen Uploads, statt die
Begrenzung zu entfernen.
Der Robot für den DigitalOcean-Export von Transloadit kann auch die Ausgabe einer Verarbeitungspipeline in Ihren Space schreiben.
