zoukankan      html  css  js  c++  java
  • asp.net mvc5 下载文件及断点续传下载

    常规下载

    控制器自带的 FileContentResult 可以让我们很方便的返回文件到服务端,减少了很多步骤。用于下载文件的时候,像视频、文本、图片这种浏览器支持的文件,默认就会被浏览器打开。这时候想让它变成下载,还需要设置一下响应头,告诉浏览器如何处理才行。

             public ActionResult DownLoadFile(String path, string fileName, string contentType)
            {
                Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(fileName));
                return File(path,contentType);
            }
    

     以上,在js使用 location.href = fileDownloadUrl 这样简单的方式即可实现在asp.net mvc5下载文件。关键是这个Content-Disposition,它的内容大概就是说明以什么方式处理,默认的文件名是什么。attachment 是以附件方式处理的意思,后面的就是文件名了,url编码处理之后可以避免那些因为带空格的文件名等等带来的问题。

    断点续传下载

            public void FileRangeDownload()
            {string fileName = "lubuntu-19.04-desktop-amd64.iso";   //客户端保存的文件名  
                string filePath = Server.MapPath($"./{fileName}");//要被下载的文件路径 
    
                var range = Request.Headers["Range"]; // Range 一般是"bytes=397506944-"
                if (!string.IsNullOrWhiteSpace(range))//如果遵守协议,支持断点续传
                {
                    using (StreamReader reader = new StreamReader(System.IO.File.OpenRead(filePath)))
                    {
                        var fileLength = new FileInfo(filePath).Length; //文件的总大小
                        fileLength = reader.BaseStream.Length;
                        long begin; //文件的开始位置
                        long end; //文件的结束位置
                        long.TryParse(range.Split('=')[1].Split('-')[0], out begin);
                        long.TryParse(range.Split('-')[1], out end);
                        end = end - begin > 0 ? end : (fileLength - 1);
    
                        //表头 表明  下载文件的开始、结束位置 和文件总大小
                        Response.AddHeader("Content-Range", "bytes " + begin + "-" + end + "/" + fileLength);
                        Response.ContentType = "application/octet-stream";
                        Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
                        Response.StatusCode = 206;
                        Response.TransmitFile(filePath, begin, (end - begin + 1)); //发送 文件开始位置读取的大小
                    }
                }
                else
                {
                    Response.ContentType = "application/octet-stream";
                    Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
                    Response.TransmitFile(filePath);
                }
            }

    注意点是从请求头读取Range,获得本次请求客户需要下载的区间,如果没有的话就是直接下载,如果有的话注意响应状态修改206,表示返回的内容是部分内容,否则断点续传继续下载可能重新下载。另外Last-Modified、ETag可用来标记资源是否更新,从而决定是否重新下载,这里不做演示。

    题外话,这个通过设置响应头来保证文件以附件形式下载的功能早在一年前就用过一次,当时看了一脸懵,也没记下来详细了解,现在又用到了,模模糊糊只记得好像在哪用过一次,当然不记得怎么写了,网上搜,一时又找不到,还是得自己一码一字的敲下来,这样印象深刻而且以后又容易找。什么转载啊,复制粘贴的都是浮云,谁码谁知道!

  • 相关阅读:
    acm python
    html cheatsheet
    unix cheatsheet
    liunx dd 读取系统文件
    比较文件内容是否相同
    linunx siege 安装
    数据库备份并压缩
    innobackupex xtrabackup 备份恢复mysql数据
    ubuntu安装rally
    解决Ubuntu显示中文乱码的问题
  • 原文地址:https://www.cnblogs.com/xxred/p/7931757.html
Copyright © 2011-2022 走看看