当前位置:  开发笔记 > 编程语言 > 正文

C#MVC从S3 Async下载大文件

如何解决《C#MVC从S3Async下载大文件》经验,为你挑选了1个好方法。

我必须从aws S3 async下载一个文件.我有一个锚标签,点击它时,一个方法将在控制器中命中下载.该文件应该在浏览器底部开始下载,就像其他文件下载一样.

在视图中

Click here

在控制器中

public void action()
{
     try
     {
           AmazonS3Client client = new AmazonS3Client(accessKeyID, secretAccessKey);
           GetObjectRequest req = new GetObjectRequest();
           req.Key = originalName;
           req.BucketName = ConfigurationManager.AppSettings["bucketName"].ToString() + DownloadPath;
           FileInfo fi = new FileInfo(originalName);
           string ext = fi.Extension.ToLower();
           string mimeType = ReturnmimeType(ext);
           var res = client.GetObject(req);
           Stream responseStream = res.ResponseStream;
           Stream response = responseStream;
           return File(response, mimeType, downLoadName);
     }
     catch (Exception)
     {
           failure = "File download failed. Please try after some time.";   
     }              
}

上述功能使浏览器加载,直到文件完全下载.然后只在底部显示该文件.我看不到mb是如何下载的.
提前致谢.



1> Akash Kava..:

您必须发送ContentLength给客户才能显示进度.浏览器没有关于它将接收多少数据的信息.

如果查看方法FileStreamResult使用的类的来源File,它不会通知客户"Content-Length".https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/FileStreamResult.cs

替换这个,

return File(response, mimeType, downLoadName);

return new FileStreamResultEx(response, res.ContentLength, mimeType, downloadName);


public class FileStreamResultEx : ActionResult{

     public FileStreamResultEx(
        Stream stream, 
        long contentLength,         
        string mimeType,
        string fileName){
        this.stream = stream;
        this.mimeType = mimeType;
        this.fileName = fileName;
        this.contentLength = contentLength;
     }


     public override void ExecuteResult(
         ControllerContext context)
     {
         var response = context.HttpContext.Response; 
         response.BufferOutput = false;
         response.Headers.Add("Content-Type", mimeType);
         response.Headers.Add("Content-Length", contentLength.ToString());
         response.Headers.Add("Content-Disposition","attachment; filename=" + fileName);

         using(stream) { 
             stream.CopyTo(response.OutputStream);
         }
     }

}

替代

通常,从服务器下载和传送S3文件是一种不好的做法.您的主机帐户将收取两倍的带宽费用.相反,您可以使用签名URL来传递非公共S3对象,只需几秒钟的时间.您只需使用Pre-Signed-URL即可

 public ActionResult Action(){
     try{
         using(AmazonS3Client client = 
              new AmazonS3Client(accessKeyID, secretAccessKey)){
            var bucketName = 
                 ConfigurationManager.AppSettings["bucketName"]
                .ToString() + DownloadPath;
            GetPreSignedUrlRequest request1 = 
               new GetPreSignedUrlRequest(){
                  BucketName = bucketName,
                  Key = originalName,
                  Expires = DateTime.Now.AddMinutes(5)
               };

            string url = client.GetPreSignedURL(request1);
            return Redirect(url);
         }
     }
     catch (Exception)
     {
         failure = "File download failed. Please try after some time.";   
     }              
 }

只要对象没有公共读取策略,没有签名的用户就无法访问对象.

此外,您必须使用usingaround AmazonS3Client来快速处理网络资源,或者只使用一个静态实例来AmazonS3Client减少不必要的分配和释放.

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有