I am using AWSSDK.S3
version 3.3.17.2
and AWSSDK.Core
version 3.3.21.16
to upload a file and then download the same file. The code below not able to download the file if the file name has spaces ( or #
)
public class AmazonS3
{
public async Task<string> UploadFileAsync(string sourceFile, string s3BucketUrl)
{
AmazonS3Uri s3Uri = new AmazonS3Uri(s3BucketUrl);
using (var s3 = new AmazonS3Client(s3Uri.Region))
{
using (TransferUtility utility = new TransferUtility(s3))
{
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest
{
BucketName = s3Uri.Bucket,
ContentType = "application/pdf",
FilePath = sourceFile,
Key = s3Uri.Key + Path.GetFileName(sourceFile),
};
await utility.UploadAsync(request).ConfigureAwait(false);
}
}
return Path.Combine(s3BucketUrl, Path.GetFileName(sourceFile));
}
public async Task DownloadFileAsync(string destinationFilePath, string s3Url)
{
var s3Uri = new AmazonS3Uri(s3Url);
var s3Client = new AmazonS3Client(s3Uri.Region);
GetObjectRequest getObjectRequest = new GetObjectRequest
{
BucketName = s3Uri.Bucket,
Key = s3Uri.Key
};
// dispose the underline stream when writing to local file system is done
using (var getObjectResponse = await s3Client.GetObjectAsync(getObjectRequest).ConfigureAwait(false))
{
await getObjectResponse.WriteResponseStreamToFileAsync(destinationFilePath, false, default(System.Threading.CancellationToken)).ConfigureAwait(false);
}
}
}
Then for testing purpose i am uploading the file and downloading the same file again
AmazonS3 s3 = new AmazonS3();
var uploadedFileS3Link = await s3.UploadFileAsync("C:\\temp\\my test file.pdf", @"https://mybucket.s3-us-west-2.amazonaws.com/development/test/");
// get exception at line below
await s3.DownloadFileAsync("C:\\temp\\downloaded file.pdf",uploadedFileS3Link );
I am getting exception
Amazon.S3.AmazonS3Exception: The specified key does not exist. ---> Amazon.Runtime.Internal.HttpErrorResponseException: The remote server returned an error: (404) Not Found. ---> System.Net.WebException: The remote server returned an error: (404) Not Found. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func
2 endFunction, Action1 endAction, Task
1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at ......
removed remaining exception for brevity
The file does exist inside bucket. In-fact i can copy and paste the s3url (i.e. the value of uploadedFileS3Link
variable) and download the file via browser.
(Note that in reality i am trying to download 1000+ files that are already uploaded with spaces in their name. So removing the spaces while uploading is not an option)
Update 1 i noticed S3 browser Url Encode the file name
I tried downloading the file using the encoded file path https://mybucket.s3-us-west-2.amazonaws.com/development/test/my%20test%20file.pdf
but it still did not work