/// /// Streams the prepared documents into a ZIP archive written directly onto /// public async Task WriteZipArchiveAsync( OrgSlug orgSlug, IEnumerable documents, Stream destination, CancellationToken cancellationToken) { await using var zip = await ZipArchive.CreateAsync( destination, ZipArchiveMode.Create, leaveOpen: true, entryNameEncoding: null, cancellationToken); foreach (var path in documents) { var key = new DocumentKey(orgSlug, path.Type, path.Name); using var response = await TryGetObjectAsync(new GetObjectRequest { BucketName = _settings.S3.Bucket, Key = key.ToString(), }, cancellationToken); if (response is null) continue; var entry = zip.CreateEntry(path.ToString(), CompressionLevel.Optimal); await using var entryStream = await entry.OpenAsync(cancellationToken); await response.ResponseStream.CopyToAsync(entryStream, cancellationToken); } } private async Task TryGetObjectAsync(GetObjectRequest request, CancellationToken cancellationToken) { try { return await s3.GetObjectAsync(request, cancellationToken); } catch (AmazonS3Exception exception) when (exception.StatusCode == HttpStatusCode.NotFound) { return null; } }