Upload or download large files to and from Amazon S3 using an AWS SDK
The following code examples show how to upload or download large files to and from Amazon S3.
For more information, see Uploading an object using multipart upload.
- SDK for .NET
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository
. Call functions that transfer files to and from an S3 bucket using the Amazon S3 TransferUtility.
global using System.Text; global using Amazon.S3; global using Amazon.S3.Model; global using Amazon.S3.Transfer; global using TransferUtilityBasics; // This Amazon S3 client uses the default user credentials // defined for this computer. using Microsoft.Extensions.Configuration; IAmazonS3 client = new AmazonS3Client(); var transferUtil = new TransferUtility(client); IConfiguration _configuration; _configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("settings.json") // Load test settings from JSON file. .AddJsonFile("settings.local.json", true) // Optionally load local settings. .Build(); // Edit the values in settings.json to use an S3 bucket and files that // exist on your AWS account and on the local computer where you // run this scenario. var bucketName = _configuration["BucketName"]; var localPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\TransferFolder"; DisplayInstructions(); PressEnter(); Console.WriteLine(); // Upload a single file to an S3 bucket. DisplayTitle("Upload a single file"); var fileToUpload = _configuration["FileToUpload"]; Console.WriteLine($"Uploading {fileToUpload} to the S3 bucket, {bucketName}."); var success = await TransferMethods.UploadSingleFileAsync(transferUtil, bucketName, fileToUpload, localPath); if (success) { Console.WriteLine($"Successfully uploaded the file, {fileToUpload} to {bucketName}."); } PressEnter(); // Upload a local directory to an S3 bucket. DisplayTitle("Upload all files from a local directory"); Console.WriteLine("Upload all the files in a local folder to an S3 bucket."); const string keyPrefix = "UploadFolder"; var uploadPath = $"{localPath}\\UploadFolder"; Console.WriteLine($"Uploading the files in {uploadPath} to {bucketName}"); DisplayTitle($"{uploadPath} files"); DisplayLocalFiles(uploadPath); Console.WriteLine(); PressEnter(); success = await TransferMethods.UploadFullDirectoryAsync(transferUtil, bucketName, keyPrefix, uploadPath); if (success) { Console.WriteLine($"Successfully uploaded the files in {uploadPath} to {bucketName}."); Console.WriteLine($"{bucketName} currently contains the following files:"); await DisplayBucketFiles(client, bucketName, keyPrefix); Console.WriteLine(); } PressEnter(); // Download a single file from an S3 bucket. DisplayTitle("Download a single file"); Console.WriteLine("Now we will download a single file from an S3 bucket."); var keyName = _configuration["FileToDownload"]; Console.WriteLine($"Downloading {keyName} from {bucketName}."); success = await TransferMethods.DownloadSingleFileAsync(transferUtil, bucketName, keyName, localPath); if (success) { Console.WriteLine("$Successfully downloaded the file, {keyName} from {bucketName}."); } PressEnter(); // Download the contents of a directory from an S3 bucket. DisplayTitle("Download the contents of an S3 bucket"); var s3Path = _configuration["S3Path"]; var downloadPath = $"{localPath}\\{s3Path}"; Console.WriteLine($"Downloading the contents of {bucketName}\\{s3Path}"); Console.WriteLine($"{bucketName}\\{s3Path} contains the following files:"); await DisplayBucketFiles(client, bucketName, s3Path); Console.WriteLine(); success = await TransferMethods.DownloadS3DirectoryAsync(transferUtil, bucketName, s3Path, downloadPath); if (success) { Console.WriteLine($"Downloaded the files in {bucketName} to {downloadPath}."); Console.WriteLine($"{downloadPath} now contains the following files:"); DisplayLocalFiles(downloadPath); } Console.WriteLine("\nThe TransferUtility Basics application has completed."); PressEnter(); // Displays the title for a section of the scenario. static void DisplayTitle(string titleText) { var sepBar = new string('-', Console.WindowWidth); Console.WriteLine(sepBar); Console.WriteLine(CenterText(titleText)); Console.WriteLine(sepBar); } // Displays a description of the actions to be performed by the scenario. static void DisplayInstructions() { var sepBar = new string('-', Console.WindowWidth); DisplayTitle("Amazon S3 Transfer Utility Basics"); Console.WriteLine("This program shows how to use the Amazon S3 Transfer Utility."); Console.WriteLine("It performs the following actions:"); Console.WriteLine("\t1. Upload a single object to an S3 bucket."); Console.WriteLine("\t2. Upload an entire directory from the local computer to an\n\t S3 bucket."); Console.WriteLine("\t3. Download a single object from an S3 bucket."); Console.WriteLine("\t4. Download the objects in an S3 bucket to a local directory."); Console.WriteLine($"\n{sepBar}"); } // Pauses the scenario. static void PressEnter() { Console.WriteLine("Press <Enter> to continue."); _ = Console.ReadLine(); Console.WriteLine("\n"); } // Returns the string textToCenter, padded on the left with spaces // that center the text on the console display. static string CenterText(string textToCenter) { var centeredText = new StringBuilder(); var screenWidth = Console.WindowWidth; centeredText.Append(new string(' ', (int)(screenWidth - textToCenter.Length) / 2)); centeredText.Append(textToCenter); return centeredText.ToString(); } // Displays a list of file names included in the specified path. static void DisplayLocalFiles(string localPath) { var fileList = Directory.GetFiles(localPath); if (fileList.Length > 0) { foreach (var fileName in fileList) { Console.WriteLine(fileName); } } } // Displays a list of the files in the specified S3 bucket and prefix. static async Task DisplayBucketFiles(IAmazonS3 client, string bucketName, string s3Path) { ListObjectsV2Request request = new() { BucketName = bucketName, Prefix = s3Path, MaxKeys = 5, }; var response = new ListObjectsV2Response(); do { response = await client.ListObjectsV2Async(request); response.S3Objects .ForEach(obj => Console.WriteLine($"{obj.Key}")); // If the response is truncated, set the request ContinuationToken // from the NextContinuationToken property of the response. request.ContinuationToken = response.NextContinuationToken; } while (response.IsTruncated); }
Upload a single file.
/// <summary> /// Uploads a single file from the local computer to an S3 bucket. /// </summary> /// <param name="transferUtil">The transfer initialized TransferUtility /// object.</param> /// <param name="bucketName">The name of the S3 bucket where the file /// will be stored.</param> /// <param name="fileName">The name of the file to upload.</param> /// <param name="localPath">The local path where the file is stored.</param> /// <returns>A boolean value indicating the success of the action.</returns> public static async Task<bool> UploadSingleFileAsync( TransferUtility transferUtil, string bucketName, string fileName, string localPath) { if (File.Exists($"{localPath}\\{fileName}")) { try { await transferUtil.UploadAsync(new TransferUtilityUploadRequest { BucketName = bucketName, Key = fileName, FilePath = $"{localPath}\\{fileName}", }); return true; } catch (AmazonS3Exception s3Ex) { Console.WriteLine($"Could not upload {fileName} from {localPath} because:"); Console.WriteLine(s3Ex.Message); return false; } } else { Console.WriteLine($"{fileName} does not exist in {localPath}"); return false; } }
Upload an entire local directory.
/// <summary> /// Uploads all the files in a local directory to a directory in an S3 /// bucket. /// </summary> /// <param name="transferUtil">The transfer initialized TransferUtility /// object.</param> /// <param name="bucketName">The name of the S3 bucket where the files /// will be stored.</param> /// <param name="keyPrefix">The key prefix is the S3 directory where /// the files will be stored.</param> /// <param name="localPath">The local directory that contains the files /// to be uploaded.</param> /// <returns>A Boolean value representing the success of the action.</returns> public static async Task<bool> UploadFullDirectoryAsync( TransferUtility transferUtil, string bucketName, string keyPrefix, string localPath) { if (Directory.Exists(localPath)) { try { await transferUtil.UploadDirectoryAsync(new TransferUtilityUploadDirectoryRequest { BucketName = bucketName, KeyPrefix = keyPrefix, Directory = localPath, }); return true; } catch (AmazonS3Exception s3Ex) { Console.WriteLine($"Can't upload the contents of {localPath} because:"); Console.WriteLine(s3Ex?.Message); return false; } } else { Console.WriteLine($"The directory {localPath} does not exist."); return false; } }
Download a single file.
/// <summary> /// Download a single file from an S3 bucket to the local computer. /// </summary> /// <param name="transferUtil">The transfer initialized TransferUtility /// object.</param> /// <param name="bucketName">The name of the S3 bucket containing the /// file to download.</param> /// <param name="keyName">The name of the file to download.</param> /// <param name="localPath">The path on the local computer where the /// downloaded file will be saved.</param> /// <returns>A Boolean value indicating the results of the action.</returns> public static async Task<bool> DownloadSingleFileAsync( TransferUtility transferUtil, string bucketName, string keyName, string localPath) { await transferUtil.DownloadAsync(new TransferUtilityDownloadRequest { BucketName = bucketName, Key = keyName, FilePath = $"{localPath}\\{keyName}", }); return (File.Exists($"{localPath}\\{keyName}")); }
Download contents of an S3 bucket.
/// <summary> /// Downloads the contents of a directory in an S3 bucket to a /// directory on the local computer. /// </summary> /// <param name="transferUtil">The transfer initialized TransferUtility /// object.</param> /// <param name="bucketName">The bucket containing the files to download.</param> /// <param name="s3Path">The S3 directory where the files are located.</param> /// <param name="localPath">The local path to which the files will be /// saved.</param> /// <returns>A Boolean value representing the success of the action.</returns> public static async Task<bool> DownloadS3DirectoryAsync( TransferUtility transferUtil, string bucketName, string s3Path, string localPath) { int fileCount = 0; // If the directory doesn't exist, it will be created. if (Directory.Exists(s3Path)) { var files = Directory.GetFiles(localPath); fileCount = files.Length; } await transferUtil.DownloadDirectoryAsync(new TransferUtilityDownloadDirectoryRequest { BucketName = bucketName, LocalDirectory = localPath, S3Directory = s3Path, }); if (Directory.Exists(localPath)) { var files = Directory.GetFiles(localPath); if (files.Length > fileCount) { return true; } // No change in the number of files. Assume // the download failed. return false; } // The local directory doesn't exist. No files // were downloaded. return false; }
Track the progress of an upload using the TransferUtility.
using System; using System.Threading.Tasks; using Amazon.S3; using Amazon.S3.Transfer; /// <summary> /// This example shows how to track the progress of a multipart upload /// using the Amazon Simple Storage Service (Amazon S3) TransferUtility to /// upload to an Amazon S3 bucket. /// </summary> public class TrackMPUUsingHighLevelAPI { public static async Task Main() { string bucketName = "amzn-s3-demo-bucket"; string keyName = "sample_pic.png"; string path = "filepath/directory/"; string filePath = $"{path}{keyName}"; // If the AWS Region defined for your default user is different // from the Region where your Amazon S3 bucket is located, // pass the Region name to the Amazon S3 client object's constructor. // For example: RegionEndpoint.USWest2 or RegionEndpoint.USEast2. IAmazonS3 client = new AmazonS3Client(); await TrackMPUAsync(client, bucketName, filePath, keyName); } /// <summary> /// Starts an Amazon S3 multipart upload and assigns an event handler to /// track the progress of the upload. /// </summary> /// <param name="client">The initialized Amazon S3 client object used to /// perform the multipart upload.</param> /// <param name="bucketName">The name of the bucket to which to upload /// the file.</param> /// <param name="filePath">The path, including the file name of the /// file to be uploaded to the Amazon S3 bucket.</param> /// <param name="keyName">The file name to be used in the /// destination Amazon S3 bucket.</param> public static async Task TrackMPUAsync( IAmazonS3 client, string bucketName, string filePath, string keyName) { try { var fileTransferUtility = new TransferUtility(client); // Use TransferUtilityUploadRequest to configure options. // In this example we subscribe to an event. var uploadRequest = new TransferUtilityUploadRequest { BucketName = bucketName, FilePath = filePath, Key = keyName, }; uploadRequest.UploadProgressEvent += new EventHandler<UploadProgressArgs>( UploadRequest_UploadPartProgressEvent); await fileTransferUtility.UploadAsync(uploadRequest); Console.WriteLine("Upload completed"); } catch (AmazonS3Exception ex) { Console.WriteLine($"Error:: {ex.Message}"); } } /// <summary> /// Event handler to check the progress of the multipart upload. /// </summary> /// <param name="sender">The object that raised the event.</param> /// <param name="e">The object that contains multipart upload /// information.</param> public static void UploadRequest_UploadPartProgressEvent(object sender, UploadProgressArgs e) { // Process event. Console.WriteLine($"{e.TransferredBytes}/{e.TotalBytes}"); } }
Upload an object with encryption.
using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Threading.Tasks; using Amazon.S3; using Amazon.S3.Model; /// <summary> /// Uses the Amazon Simple Storage Service (Amazon S3) low level API to /// perform a multipart upload to an Amazon S3 bucket. /// </summary> public class SSECLowLevelMPUcopyObject { public static async Task Main() { string existingBucketName = "amzn-s3-demo-bucket"; string sourceKeyName = "sample_file.txt"; string targetKeyName = "sample_file_copy.txt"; string filePath = $"sample\\{targetKeyName}"; // If the AWS Region defined for your default user is different // from the Region where your Amazon S3 bucket is located, // pass the Region name to the Amazon S3 client object's constructor. // For example: RegionEndpoint.USEast1. IAmazonS3 client = new AmazonS3Client(); // Create the encryption key. var base64Key = CreateEncryptionKey(); await CreateSampleObjUsingClientEncryptionKeyAsync( client, existingBucketName, sourceKeyName, filePath, base64Key); } /// <summary> /// Creates the encryption key to use with the multipart upload. /// </summary> /// <returns>A string containing the base64-encoded key for encrypting /// the multipart upload.</returns> public static string CreateEncryptionKey() { Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); string base64Key = Convert.ToBase64String(aesEncryption.Key); return base64Key; } /// <summary> /// Creates and uploads an object using a multipart upload. /// </summary> /// <param name="client">The initialized Amazon S3 object used to /// initialize and perform the multipart upload.</param> /// <param name="existingBucketName">The name of the bucket to which /// the object will be uploaded.</param> /// <param name="sourceKeyName">The source object name.</param> /// <param name="filePath">The location of the source object.</param> /// <param name="base64Key">The encryption key to use with the upload.</param> public static async Task CreateSampleObjUsingClientEncryptionKeyAsync( IAmazonS3 client, string existingBucketName, string sourceKeyName, string filePath, string base64Key) { List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>(); InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, }; InitiateMultipartUploadResponse initResponse = await client.InitiateMultipartUploadAsync(initiateRequest); long contentLength = new FileInfo(filePath).Length; long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB try { long filePosition = 0; for (int i = 1; filePosition < contentLength; i++) { UploadPartRequest uploadRequest = new UploadPartRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId, PartNumber = i, PartSize = partSize, FilePosition = filePosition, FilePath = filePath, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, }; // Upload part and add response to our list. uploadResponses.Add(await client.UploadPartAsync(uploadRequest)); filePosition += partSize; } CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId, }; completeRequest.AddPartETags(uploadResponses); CompleteMultipartUploadResponse completeUploadResponse = await client.CompleteMultipartUploadAsync(completeRequest); } catch (Exception exception) { Console.WriteLine($"Exception occurred: {exception.Message}"); // If there was an error, abort the multipart upload. AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId, }; await client.AbortMultipartUploadAsync(abortMPURequest); } } }
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.