amazon-s3 - Amazon S3 客户端无法下载带有空格或散列的文件?

标签 amazon-s3 aws-sdk aws-sdk-net

我正在使用 AWSSDK.S3版本3.3.17.2AWSSDK.Core版本3.3.21.16上传文件,然后下载相同的文件。以下代码无法下载文件如果文件名有空格(或 #)

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);
        }
    }              
}

然后为了测试目的,我上传文件并再次下载相同的文件
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 );

我得到了异常(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, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at ......



为简洁起见删除了剩余的异常(exception)

该文件确实存在于存储桶中。事实上,我可以复制并粘贴 s3url(即 uploadedFileS3Link 变量的值)并通过浏览器下载文件。

(请注意,实际上我正在尝试下载 1000 多个已上传的文件,这些文件的名称中带有空格。因此在上传时删除空格不是一种选择)

更新 1
我注意到 S3 浏览器 Url 编码文件名

enter image description here

我尝试使用编码文件路径 https://mybucket.s3-us-west-2.amazonaws.com/development/test/my%20test%20file.pdf 下载文件
但它仍然不起作用

最佳答案

所以最后我发现了问题所在。我正在使用 AmazonS3Uri类来解析给定的 S3 url 并获取 key 、存储桶和区域。 AmazonS3Uri将我的 key 返回为 development/test/my%20test%20file.pdf
因为内部AmazonS3Uri正在使用 System.Uri构建 Uri 然后返回 AbsolutePath它返回编码路径作为键(它应该返回本地路径作为键吗?)

我不知道为什么但AmazonS3Client不喜欢它,如果您传递 Encoded key ,它会抛出异常。

所以为了解决这个问题,我使用 System.Net.WebUtility.UrlDecode(s3Uri.Key) 解码 key .所以新的下载方法看起来像

    public async Task DownloadFileAsync(string destinationFilePath, string s3Url)
    {
        var s3Uri = new S3UrlParser(s3Url);
        var s3Client = new AmazonS3Client(s3Uri.Region);
        GetObjectRequest getObjectRequest = new GetObjectRequest
        {
            BucketName = s3Uri.Bucket,
            Key = System.Net.WebUtility.UrlDecode(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);
        }
    }

关于amazon-s3 - Amazon S3 客户端无法下载带有空格或散列的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49325019/

相关文章:

python - 如何跨多个 AWS Lambda 和 Elastic Beanstalk 应用程序共享模块?

ios - iOS : A server with the specified hostname could not be found 上的 AWS 转录错误

ruby - 使用 AWS SDK (v2) 从 URL 获取对象键

.net-core-2.1 - 有没有办法确定一个区域中 AWS SES 服务的可用性?

google-cloud-storage - 使用适用于 .NET 的 AWS 开发工具包上传到 Google Cloud Storage `Expected hash not equal to calculated hash`

amazon-web-services - 运行 Amazon S3 示例时出现 Amazon AWS 403 InvalidAccesskey 错误

bash - 调试我的 cron 应用程序

java - Spring Integration - FTP 下载后立即发送消息

amazon-web-services - AWS Cloudwatch 事件 putTargets 未添加 Lambda 事件源

amazon-web-services - AWS 凭证文件在 Windows 上被拒绝访问