Download a stream of unknown size from an Amazon S3 object using an AWS SDK - Amazon Simple Storage Service

Download a stream of unknown size from an Amazon S3 object using an AWS SDK

The following code example shows how to download a stream of unknown size from an Amazon S3 object.

Swift
SDK for Swift
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import ArgumentParser import AWSClientRuntime import AWSS3 import Foundation import Smithy import SmithyHTTPAPI import SmithyStreams /// Download a file from the specified bucket. /// /// - Parameters: /// - bucket: The Amazon S3 bucket name to get the file from. /// - key: The name (or path) of the file to download from the bucket. /// - destPath: The pathname on the local filesystem at which to store /// the downloaded file. func downloadFile(bucket: String, key: String, destPath: String?) async throws { let fileURL: URL // If no destination path was provided, use the key as the name to use // for the file in the downloads folder. if destPath == nil { do { try fileURL = FileManager.default.url( for: .downloadsDirectory, in: .userDomainMask, appropriateFor: URL(string: key), create: true ).appendingPathComponent(key) } catch { throw TransferError.directoryError } } else { fileURL = URL(fileURLWithPath: destPath!) } let config = try await S3Client.S3ClientConfiguration(region: region) let s3Client = S3Client(config: config) // Create a `FileHandle` referencing the local destination. Then // create a `ByteStream` from that. FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil) let fileHandle = try FileHandle(forWritingTo: fileURL) // Download the file using `GetObject`. let getInput = GetObjectInput( bucket: bucket, key: key ) do { let getOutput = try await s3Client.getObject(input: getInput) guard let body = getOutput.body else { throw TransferError.downloadError("Error: No data returned for download") } // If the body is returned as a `Data` object, write that to the // file. If it's a stream, read the stream chunk by chunk, // appending each chunk to the destination file. switch body { case .data: guard let data = try await body.readData() else { throw TransferError.downloadError("Download error") } // Write the `Data` to the file. do { try data.write(to: fileURL) } catch { throw TransferError.writeError } break case .stream(let stream as ReadableStream): while (true) { let chunk = try await stream.readAsync(upToCount: 5 * 1024 * 1024) guard let chunk = chunk else { break } // Write the chunk to the destination file. do { try fileHandle.write(contentsOf: chunk) } catch { throw TransferError.writeError } } break default: throw TransferError.downloadError("Received data is unknown object type") } } catch { throw TransferError.downloadError("Error downloading the file: \(error)") } print("File downloaded to \(fileURL.path).") }

For a complete list of AWS SDK developer guides and code examples, see Developing with Amazon S3 using the AWS SDKs. This topic also includes information about getting started and details about previous SDK versions.