.net mvc实现大文件下载
在做项目的过程中有时候会遇到“下载几十M甚至过百M的文件”这样的需求,这时候如果还是用老方法直接将文件一次性读取出来然后写入到响应流,这肯定是不行的,不说别的,光是内存的消耗就可能让服务器垮掉。那么有没有更好的方式呢,答案是肯定的,下面分享一种使用Response.OutputStream实现大文件下载的方式。
首先,自定义一个ActionResult,代码如下:
/// <summary>
/// 该类继承了ActionResult,通过重写ExecuteResult方法,进行文件的下载
/// </summary>
public class FileResult : ActionResult
{
private readonly string _filePath;//文件路径
private readonly string _fileName;//文件名称
public FileResult(string filePath, string fileName)
{
_filePath = filePath;
_fileName = fileName;
}
public override void ExecuteResult(ControllerContext context)
{
string fileName = _fileName;
HttpResponseBase response = context.HttpContext.Response;
WebClient wcClient = new WebClient();
//对远程文件发送一个请求
WebRequest webReq = WebRequest.Create(_filePath);
//接收远程WEB服务器发回的响应
WebResponse webRes = webReq.GetResponse();
//获取文件长度
long fileLength = webRes.ContentLength;
//创建一个文件流,接收返回的流信息
Stream srm = webRes.GetResponseStream();
//使用特殊编码读取流信息
StreamReader srmReader = new StreamReader(srm);
//定义缓冲区
byte[] fileBuffer = new byte[1024];
int startByte = 0;
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName));
//读取缓冲区内容
while (fileLength > 0 && response.IsClientConnected)
{
int length = srm.Read(fileBuffer, startByte, fileBuffer.Length);//每次读取1024个字节长度的内容
response.OutputStream.Write(fileBuffer, 0, length);
response.Flush();//刷新响应
fileLength = fileLength - length;
}
response.Close();//文件传输完毕,关闭相应流
srmReader.Close();
srm.Close();
}
}
这里,我用了一个47.5MB大小的pdf文件做测试,效果还是不错的。