Herunterladen eines Archivs in Amazon S3 Glacier mithilfe der AWS SDK for .NET - Amazon S3 Glacier

Diese Seite richtet sich nur an Bestandskunden des S3 Glacier-Dienstes, die Vaults und das Original REST API von 2012 verwenden.

Wenn Sie nach Archivspeicherlösungen suchen, empfehlen wir die Verwendung der S3 Glacier-Speicherklassen in Amazon S3, S3 Glacier Instant Retrieval, S3 Glacier Flexible Retrieval und S3 Glacier Deep Archive. Weitere Informationen zu diesen Speicheroptionen finden Sie unter S3 Glacier-Speicherklassen und Langfristige Datenspeicherung mit S3 Glacier-Speicherklassen im Amazon S3 S3-Benutzerhandbuch. Diese Speicherklassen verwenden Amazon S3API, sind in allen Regionen verfügbar und können in der Amazon S3 S3-Konsole verwaltet werden. Sie bieten Funktionen wie Speicherkostenanalyse, Storage Lens, erweiterte optionale Verschlüsselungsfunktionen und mehr.

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.

Herunterladen eines Archivs in Amazon S3 Glacier mithilfe der AWS SDK for .NET

Sowohl die High-Level- als auch die Low-Level-API, die vom Amazon-SDK für .NET bereitgestellt werden, bieten eine Methode zum Herunterladen eines Archivs.

Herunterladen eines Archivs mit der High-Level-API von AWS SDK for .NET

Die ArchiveTransferManager-Klasse der High-Level-API bietet die Download-Methode, mit der Sie ein Archiv herunterladen können.

Wichtig

Die ArchiveTransferManager-Klasse erstellt ein Amazon Simple Notification Service (Amazon SNS)-Thema und eine Amazon Simple Queue Service (Amazon SQS)-Warteschlange, die dieses Thema abonniert hat. Die Klasse initiiert daraufhin den Abrufauftrag für das Archiv und fragt die Warteschlange für das Archiv nach der Verfügbarkeit ab. Wenn das Archiv verfügbar ist, beginnt der Download. Weitere Informationen zu Abrufzeiten finden Sie unter Archiv-Abrufoptionen.

Beispiel: Herunterladen eines Archivs mithilfe der High-Level-API von AWS SDK for .NET

Mit dem folgenden C#-Beispielcode wird ein Archiv aus einem Tresor („examplevault“) in der Region „USA West (Oregon)“ heruntergeladen.

Eine schrittweise Anleitung für das Ausführen dieses Beispiels finden Sie unter Ausführen von Codebeispielen. Sie müssen den Code wie gezeigt mit einer vorhandenen Archiv-ID und dem lokalen Dateipfad zum Speicherort des heruntergeladenen Archivs aktualisieren.

using System; using Amazon.Glacier; using Amazon.Glacier.Transfer; using Amazon.Runtime; namespace glacier.amazon.com.rproxy.goskope.com.docsamples { class ArchiveDownloadHighLevel { static string vaultName = "examplevault"; static string archiveId = "*** Provide archive ID ***"; static string downloadFilePath = "*** Provide the file name and path to where to store the download ***"; public static void Main(string[] args) { try { var manager = new ArchiveTransferManager(Amazon.RegionEndpoint.USWest2); var options = new DownloadOptions(); options.StreamTransferProgress += ArchiveDownloadHighLevel.progress; // Download an archive. Console.WriteLine("Intiating the archive retrieval job and then polling SQS queue for the archive to be available."); Console.WriteLine("Once the archive is available, downloading will begin."); manager.Download(vaultName, archiveId, downloadFilePath, options); Console.WriteLine("To continue, press Enter"); Console.ReadKey(); } catch (AmazonGlacierException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadKey(); } static int currentPercentage = -1; static void progress(object sender, StreamTransferProgressArgs args) { if (args.PercentDone != currentPercentage) { currentPercentage = args.PercentDone; Console.WriteLine("Downloaded {0}%", args.PercentDone); } } } }

Herunterladen eines Archivs mit der Low-Level-API von AWS SDK for .NET

Nachfolgend werden die Schritte zum Herunterladen eines Amazon S3 Glacier (S3 Glacier)-Archivs mithilfe der Low-Level-API von AWS SDK for .NET beschrieben.

  1. Erstellen einer Instance der AmazonGlacierClient-Klasse (Client).

    Sie müssen die AWS-Region angeben, aus der das Archiv heruntergeladen werden soll. Alle Operationen, die Sie mit diesem Client ausführen, gelten für diese AWS-Region.

  2. Initiieren eines mehrteiligen archive-retrieval-Auftrags durch Ausführen der InitiateJob-Methode.

    Sie stellen Auftragsinformationen bereit, beispielsweise die Archiv-ID des herunterzuladenden Archivs und optional das Amazon-SNS-Thema, an das S3 Glacier bei Beendigung des Auftrags eine Nachricht übermitteln soll, indem Sie eine Instance der InitiateJobRequest-Klasse erstellen. S3 Glacier gibt als Antwort eine Auftrags-ID zurück. Die Antwort ist in einer Instance der InitiateJobResponse-Klasse verfügbar.

    AmazonGlacierClient client; client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2); InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "archive-retrieval", ArchiveId = "*** Provide archive id ***", SNSTopic = "*** Provide Amazon SNS topic ARN ***", } }; InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId;

    Sie können optional einen Bytebereich angeben, damit S3 Glacier nur einen Teil des Archivs vorbereitet, wie in der folgenden Anforderung gezeigt. Die Anforderung weist S3 Glacier an, nur den Archivbereich von 1 MB bis 2 MB vorzubereiten.

    AmazonGlacierClient client; client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2); InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "archive-retrieval", ArchiveId = "*** Provide archive id ***", SNSTopic = "*** Provide Amazon SNS topic ARN ***", } }; // Specify byte range. int ONE_MEG = 1048576; initJobRequest.JobParameters.RetrievalByteRange = string.Format("{0}-{1}", ONE_MEG, 2 * ONE_MEG -1); InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId;
  3. Warten Sie, bis der Auftrag abgeschlossen wurde.

    Sie müssen warten, bis die Ausgabe des Auftrags zum Download bereit ist. Wenn Sie eine Benachrichtigungskonfiguration für den Tresor eingerichtet haben, in der ein Amazon Simple Notification Service (Amazon SNS)-Thema angegeben ist, oder beim Initiieren des Auftrags ein Amazon-SNS-Thema angegeben haben, sendet S3 Glacier nach Beenden des Auftrags eine Benachrichtigung an das Thema. Im Codebeispiel im folgenden Abschnitt wird Amazon SNS zum Veröffentlichen einer Nachricht durch S3 Glacier verwendet.

    Sie können S3 Glacier auch durch einen Aufruf der DescribeJob-Methode abfragen, um den Abschlussstatus des Auftrags zu ermitteln. Allerdings wird die Verwendung eines Amazon-SNS-Themas für Benachrichtigungen empfohlen.

  4. Laden Sie die Auftragsausgabe (Archivdaten) herunter, indem Sie die GetJobOutput-Methode ausführen.

    Sie erstellen eine Instance der GetJobOutputRequest-Klasse, um die Informationen in der Anforderung, wie beispielsweise die Auftrags-ID und den Tresornamen, bereitzustellen. Die von S3 Glacier zurückgegebene Ausgabe ist im GetJobOutputResponse-Objekt verfügbar.

    GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; GetJobOutputResponse getJobOutputResponse = client.GetJobOutput(getJobOutputRequest); using (Stream webStream = getJobOutputResponse.Body) { using (Stream fileToSave = File.OpenWrite(fileName)) { CopyStream(webStream, fileToSave); } }

    Mit dem vorherigen Codeabschnitt wird die gesamte Auftragsausgabe heruntergeladen. Sie können optional nur einen Teil der Ausgabe abrufen oder die gesamte Ausgabe in kleineren Datenblöcken herunterladen, indem Sie den Bytebereich für GetJobOutputRequest angeben.

    GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; getJobOutputRequest.SetRange(0, 1048575); // Download only the first 1 MB chunk of the output.

    Als Reaktion auf Ihren GetJobOutput-Aufruf gibt S3 Glacier die Prüfsumme für den heruntergeladenen Teil der Daten zurück, sofern bestimmte Bedingungen erfüllt sind. Weitere Informationen finden Sie unter Erhalten von Prüfsummen bei Daten-Download.

    Zum Überprüfen, dass der Downloads fehlerfrei erfolgt ist, können Sie anschließend auf Client-Seite die Prüfsumme berechnen und mit der von S3 Glacier in der Antwort gesendeten Prüfsumme vergleichen.

    Wenn bei einem Auftrag zum Abrufen eines Archivs ein Bereich angegeben ist, enthält die abgerufene Auftragsbeschreibung die Prüfsumme für den abgerufenen Bereich (SHA256TreeHash). Sie können anhand dieses Werts die Genauigkeit für den gesamten Bytebereich verifizieren, den Sie später herunterladen. Sie können beispielsweise einen Auftrag initiieren, durch den zuerst ein mit dem Struktur-Hash abgeglichener Bereich abgerufen und dann die Ausgabe in Datenblöcken so heruntergeladen wird, dass für jede der GetJobOutput-Anforderungen eine Prüfsumme zurückgegeben wird. Anschließend können Sie die Prüfsumme für jeden auf der Clientseite heruntergeladenen Teil und schließlich das Struktur-Hash berechnen. Sie können diesen mit der Prüfsumme vergleichen, die von S3 Glacier als Antwort auf Ihre Anforderung zur Auftragsbeschreibung zurückgegeben wird, um zu überprüfen, ob der gesamte heruntergeladene Byte-Bereich mit dem in S3 Glacier gespeicherten Byte-Bereich übereinstimmt.

    Ein funktionierendes Beispiel finden Sie unter Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for .NET – Herunterladen der Ausgabe in Blöcken.

Beispiel 1: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for .NET

Mit dem folgenden C#-Beispielcode wird ein Archiv aus dem angegebenen Tresor heruntergeladen. Nachdem der Auftrag abgeschlossen ist, lädt der Beispielcode die gesamte Ausgabe in einem einzigen GetJobOutput-Aufruf herunter. Ein Beispiel für das Herunterladen der Ausgabe in Datenblöcken finden Sie unter Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for .NET – Herunterladen der Ausgabe in Blöcken.

Das Beispiel führt die folgenden Aufgaben durch:

  • Richtet ein Amazon Simple Notification Service (Amazon SNS)-Thema ein.

    S3 Glacier sendet nach Abschluss des Auftrags eine Benachrichtigung an dieses Thema.

  • Richtet eine Amazon Simple Queue Service (Amazon SQS)-Warteschlange ein.

    Im Beispiel wird der Warteschlange eine Richtlinie angefügt, damit das Amazon-SNS-Thema Nachrichten veröffentlichen kann.

  • Initiiert einen Auftrag zum Herunterladen des angegebenen Archivs.

    In der Auftragsanforderung im Beispiel wird das Amazon-SNS-Thema angegeben, damit S3 Glacier nach dem Abschluss des Auftrags eine Nachricht senden kann.

  • Überprüft regelmäßig die Amazon-SQS-Warteschlange auf Nachrichten.

    Ist eine Nachricht vorhanden, parsen Sie das JSON und prüfen Sie, ob der Auftrag erfolgreich abgeschlossen wurde. Wenn eine Nachricht enthalten ist, laden Sie das Archiv herunter. Im Codebeispiel wird die JSON.NET-Bibliothek (siehe JSON.NET) zum Analysieren von JSON verwendet.

  • Bereinigt das System durch Löschen des Amazon-SNS-Themas und der erstellten Amazon-SQS-Warteschlange.

using System; using System.Collections.Generic; using System.IO; using System.Threading; using Amazon.Glacier; using Amazon.Glacier.Model; using Amazon.Runtime; using Amazon.SimpleNotificationService; using Amazon.SimpleNotificationService.Model; using Amazon.SQS; using Amazon.SQS.Model; using Newtonsoft.Json; namespace glacier.amazon.com.rproxy.goskope.com.docsamples { class ArchiveDownloadLowLevelUsingSNSSQS { static string topicArn; static string queueUrl; static string queueArn; static string vaultName = "*** Provide vault name ***"; static string archiveID = "*** Provide archive ID ***"; static string fileName = "*** Provide the file name and path to where to store downloaded archive ***"; static AmazonSimpleNotificationServiceClient snsClient; static AmazonSQSClient sqsClient; const string SQS_POLICY = "{" + " \"Version\" : \"2012-10-17\"," + " \"Statement\" : [" + " {" + " \"Sid\" : \"sns-rule\"," + " \"Effect\" : \"Allow\"," + " \"Principal\" : {\"Service\" : \"sns.amazonaws.com\" }," + " \"Action\" : \"sqs:SendMessage\"," + " \"Resource\" : \"{QueueArn}\"," + " \"Condition\" : {" + " \"ArnLike\" : {" + " \"aws:SourceArn\" : \"{TopicArn}\"" + " }" + " }" + " }" + " ]" + "}"; public static void Main(string[] args) { AmazonGlacierClient client; try { using (client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2)) { Console.WriteLine("Setup SNS topic and SQS queue."); SetupTopicAndQueue(); Console.WriteLine("To continue, press Enter"); Console.ReadKey(); Console.WriteLine("Retrieving..."); RetrieveArchive(client); } Console.WriteLine("Operations successful. To continue, press Enter"); Console.ReadKey(); } catch (AmazonGlacierException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } finally { // Delete SNS topic and SQS queue. snsClient.DeleteTopic(new DeleteTopicRequest() { TopicArn = topicArn }); sqsClient.DeleteQueue(new DeleteQueueRequest() { QueueUrl = queueUrl }); } } static void SetupTopicAndQueue() { snsClient = new AmazonSimpleNotificationServiceClient(Amazon.RegionEndpoint.USWest2); sqsClient = new AmazonSQSClient(Amazon.RegionEndpoint.USWest2); long ticks = DateTime.Now.Ticks; topicArn = snsClient.CreateTopic(new CreateTopicRequest { Name = "GlacierDownload-" + ticks }).TopicArn; Console.Write("topicArn: "); Console.WriteLine(topicArn); CreateQueueRequest createQueueRequest = new CreateQueueRequest(); createQueueRequest.QueueName = "GlacierDownload-" + ticks; CreateQueueResponse createQueueResponse = sqsClient.CreateQueue(createQueueRequest); queueUrl = createQueueResponse.QueueUrl; Console.Write("QueueURL: "); Console.WriteLine(queueUrl); GetQueueAttributesRequest getQueueAttributesRequest = new GetQueueAttributesRequest(); getQueueAttributesRequest.AttributeNames = new List<string> { "QueueArn" }; getQueueAttributesRequest.QueueUrl = queueUrl; GetQueueAttributesResponse response = sqsClient.GetQueueAttributes(getQueueAttributesRequest); queueArn = response.QueueARN; Console.Write("QueueArn: "); Console.WriteLine(queueArn); // Setup the Amazon SNS topic to publish to the SQS queue. snsClient.Subscribe(new SubscribeRequest() { Protocol = "sqs", Endpoint = queueArn, TopicArn = topicArn }); // Add policy to the queue so SNS can send messages to the queue. var policy = SQS_POLICY.Replace("{TopicArn}", topicArn).Replace("{QueueArn}", queueArn); sqsClient.SetQueueAttributes(new SetQueueAttributesRequest() { QueueUrl = queueUrl, Attributes = new Dictionary<string, string> { { QueueAttributeName.Policy, policy } } }); } static void RetrieveArchive(AmazonGlacierClient client) { // Initiate job. InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "archive-retrieval", ArchiveId = archiveID, Description = "This job is to download archive.", SNSTopic = topicArn, } }; InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId; // Check queue for a message and if job completed successfully, download archive. ProcessQueue(jobId, client); } private static void ProcessQueue(string jobId, AmazonGlacierClient client) { ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest() { QueueUrl = queueUrl, MaxNumberOfMessages = 1 }; bool jobDone = false; while (!jobDone) { Console.WriteLine("Poll SQS queue"); ReceiveMessageResponse receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest); if (receiveMessageResponse.Messages.Count == 0) { Thread.Sleep(10000 * 60); continue; } Console.WriteLine("Got message"); Message message = receiveMessageResponse.Messages[0]; Dictionary<string, string> outerLayer = JsonConvert.DeserializeObject<Dictionary<string, string>>(message.Body); Dictionary<string, object> fields = JsonConvert.DeserializeObject<Dictionary<string, object>>(outerLayer["Message"]); string statusCode = fields["StatusCode"] as string; if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_SUCCEEDED, StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Downloading job output"); DownloadOutput(jobId, client); // Save job output to the specified file location. } else if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_FAILED, StringComparison.InvariantCultureIgnoreCase)) Console.WriteLine("Job failed... cannot download the archive."); jobDone = true; sqsClient.DeleteMessage(new DeleteMessageRequest() { QueueUrl = queueUrl, ReceiptHandle = message.ReceiptHandle }); } } private static void DownloadOutput(string jobId, AmazonGlacierClient client) { GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; GetJobOutputResponse getJobOutputResponse = client.GetJobOutput(getJobOutputRequest); using (Stream webStream = getJobOutputResponse.Body) { using (Stream fileToSave = File.OpenWrite(fileName)) { CopyStream(webStream, fileToSave); } } } public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[65536]; int length; while ((length = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, length); } } } }

Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for .NET – Herunterladen der Ausgabe in Blöcken

Das folgende C#-Codebeispiel ruft ein Archiv aus S3 Glacier ab. Der Beispielcode gibt den abzurufenden Bytebereich in einem GetJobOutputRequest-Objekt an und lädt die Auftragsausgabe in Datenblöcken herunter.

using System; using System.Collections.Generic; using System.IO; using System.Threading; using Amazon.Glacier; using Amazon.Glacier.Model; using Amazon.Glacier.Transfer; using Amazon.Runtime; using Amazon.SimpleNotificationService; using Amazon.SimpleNotificationService.Model; using Amazon.SQS; using Amazon.SQS.Model; using Newtonsoft.Json; using System.Collections.Specialized; namespace glacier.amazon.com.rproxy.goskope.com.docsamples { class ArchiveDownloadLowLevelUsingSQLSNSOutputUsingRange { static string topicArn; static string queueUrl; static string queueArn; static string vaultName = "*** Provide vault name ***"; static string archiveId = "*** Provide archive ID ***"; static string fileName = "*** Provide the file name and path to where to store downloaded archive ***"; static AmazonSimpleNotificationServiceClient snsClient; static AmazonSQSClient sqsClient; const string SQS_POLICY = "{" + " \"Version\" : \"2012-10-17\"," + " \"Statement\" : [" + " {" + " \"Sid\" : \"sns-rule\"," + " \"Effect\" : \"Allow\"," + " \"Principal\" : {\"AWS\" : \"arn:aws:iam::123456789012:root\" }," + " \"Action\" : \"sqs:SendMessage\"," + " \"Resource\" : \"{QuernArn}\"," + " \"Condition\" : {" + " \"ArnLike\" : {" + " \"aws:SourceArn\" : \"{TopicArn}\"" + " }" + " }" + " }" + " ]" + "}"; public static void Main(string[] args) { AmazonGlacierClient client; try { using (client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2)) { Console.WriteLine("Setup SNS topic and SQS queue."); SetupTopicAndQueue(); Console.WriteLine("To continue, press Enter"); Console.ReadKey(); Console.WriteLine("Download archive"); DownloadAnArchive(archiveId, client); } Console.WriteLine("Operations successful. To continue, press Enter"); Console.ReadKey(); } catch (AmazonGlacierException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } finally { // Delete SNS topic and SQS queue. snsClient.DeleteTopic(new DeleteTopicRequest() { TopicArn = topicArn }); sqsClient.DeleteQueue(new DeleteQueueRequest() { QueueUrl = queueUrl }); } } static void SetupTopicAndQueue() { long ticks = DateTime.Now.Ticks; // Setup SNS topic. snsClient = new AmazonSimpleNotificationServiceClient(Amazon.RegionEndpoint.USWest2); sqsClient = new AmazonSQSClient(Amazon.RegionEndpoint.USWest2); topicArn = snsClient.CreateTopic(new CreateTopicRequest { Name = "GlacierDownload-" + ticks }).TopicArn; Console.Write("topicArn: "); Console.WriteLine(topicArn); CreateQueueRequest createQueueRequest = new CreateQueueRequest(); createQueueRequest.QueueName = "GlacierDownload-" + ticks; CreateQueueResponse createQueueResponse = sqsClient.CreateQueue(createQueueRequest); queueUrl = createQueueResponse.QueueUrl; Console.Write("QueueURL: "); Console.WriteLine(queueUrl); GetQueueAttributesRequest getQueueAttributesRequest = new GetQueueAttributesRequest(); getQueueAttributesRequest.AttributeNames = new List<string> { "QueueArn" }; getQueueAttributesRequest.QueueUrl = queueUrl; GetQueueAttributesResponse response = sqsClient.GetQueueAttributes(getQueueAttributesRequest); queueArn = response.QueueARN; Console.Write("QueueArn: "); Console.WriteLine(queueArn); // Setup the Amazon SNS topic to publish to the SQS queue. snsClient.Subscribe(new SubscribeRequest() { Protocol = "sqs", Endpoint = queueArn, TopicArn = topicArn }); // Add the policy to the queue so SNS can send messages to the queue. var policy = SQS_POLICY.Replace("{TopicArn}", topicArn).Replace("{QuernArn}", queueArn); sqsClient.SetQueueAttributes(new SetQueueAttributesRequest() { QueueUrl = queueUrl, Attributes = new Dictionary<string, string> { { QueueAttributeName.Policy, policy } } }); } static void DownloadAnArchive(string archiveId, AmazonGlacierClient client) { // Initiate job. InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "archive-retrieval", ArchiveId = archiveId, Description = "This job is to download the archive.", SNSTopic = topicArn, } }; InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId; // Check queue for a message and if job completed successfully, download archive. ProcessQueue(jobId, client); } private static void ProcessQueue(string jobId, AmazonGlacierClient client) { var receiveMessageRequest = new ReceiveMessageRequest() { QueueUrl = queueUrl, MaxNumberOfMessages = 1 }; bool jobDone = false; while (!jobDone) { Console.WriteLine("Poll SQS queue"); ReceiveMessageResponse receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest); if (receiveMessageResponse.Messages.Count == 0) { Thread.Sleep(10000 * 60); continue; } Console.WriteLine("Got message"); Message message = receiveMessageResponse.Messages[0]; Dictionary<string, string> outerLayer = JsonConvert.DeserializeObject<Dictionary<string, string>>(message.Body); Dictionary<string, object> fields = JsonConvert.DeserializeObject<Dictionary<string, object>>(outerLayer["Message"]); string statusCode = fields["StatusCode"] as string; if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_SUCCEEDED, StringComparison.InvariantCultureIgnoreCase)) { long archiveSize = Convert.ToInt64(fields["ArchiveSizeInBytes"]); Console.WriteLine("Downloading job output"); DownloadOutput(jobId, archiveSize, client); // This where we save job output to the specified file location. } else if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_FAILED, StringComparison.InvariantCultureIgnoreCase)) Console.WriteLine("Job failed... cannot download the archive."); jobDone = true; sqsClient.DeleteMessage(new DeleteMessageRequest() { QueueUrl = queueUrl, ReceiptHandle = message.ReceiptHandle }); } } private static void DownloadOutput(string jobId, long archiveSize, AmazonGlacierClient client) { long partSize = 4 * (long)Math.Pow(2, 20); // 4 MB. using (Stream fileToSave = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { long currentPosition = 0; do { GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; long endPosition = currentPosition + partSize - 1; if (endPosition > archiveSize) endPosition = archiveSize; getJobOutputRequest.SetRange(currentPosition, endPosition); GetJobOutputResponse getJobOutputResponse = client.GetJobOutput(getJobOutputRequest); using (Stream webStream = getJobOutputResponse.Body) { CopyStream(webStream, fileToSave); } currentPosition += partSize; } while (currentPosition < archiveSize); } } public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[65536]; int length; while ((length = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, length); } } } }