当我们的ASP.NET Core网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃。可以参考如下代码来避免这个问题。
 
关于此代码的几点说明:
  1. 将数据分成较小的部分,然后将其移动到响应输出流以供下载,从而获取这些数据。
  2. 根据下载的文件类型来指定 Response.ContentType 。(这个网址可以找到大部分文件类型的对照表:http://tool.oschina.net/commons
  3. 在每次调用Response.Body.Write后记得调用 Response.Body.Flush()
  4. 在循环下载的过程中使用 HttpContext.RequestAborted.IsCancellationRequested 这个判断可以帮助程序尽早发现连接是否正常。若不正常,可以及早放弃下载,以释放所占用的服务器资源。
 
本例使用ASP.NET Core MVC中Controller的Action来演示大文件的下载代码,根据需要也可以改为其它方式(例如ASP.NET Core的中间件)来做下载。
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Web; namespace AspNetCoreDownload.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
} /// <summary>
/// DownloadBigFile用于下载大文件,循环读取大文件的内容到服务器内存,然后发送给客户端浏览器
/// </summary>
public IActionResult DownloadBigFile()
{
var filePath = @"D:\Download\测试文档.xlsx";//要下载的文件地址,这个文件会被分成片段,通过循环逐步读取到ASP.NET Core中,然后发送给客户端浏览器
var fileName = Path.GetFileName(filePath);//测试文档.xlsx int bufferSize = ;//这就是ASP.NET Core循环读取下载文件的缓存大小,这里我们设置为了1024字节,也就是说ASP.NET Core每次会从下载文件中读取1024字节的内容到服务器内存中,然后发送到客户端浏览器,这样避免了一次将整个下载文件都加载到服务器内存中,导致服务器崩溃 Response.ContentType = "application/vnd.ms-excel";//由于我们下载的是一个Excel文件,所以设置ContentType为application/vnd.ms-excel var contentDisposition = "attachment;" + "filename=" + HttpUtility.UrlEncode(fileName);//在Response的Header中设置下载文件的文件名,这样客户端浏览器才能正确显示下载的文件名,注意这里要用HttpUtility.UrlEncode编码文件名,否则有些浏览器可能会显示乱码文件名
Response.Headers.Add("Content-Disposition", new string[] { contentDisposition }); //使用FileStream开始循环读取要下载文件的内容
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (Response.Body)//调用Response.Body.Dispose()并不会关闭客户端浏览器到ASP.NET Core服务器的连接,之后还可以继续往Response.Body中写入数据
{
long contentLength = fs.Length;//获取下载文件的大小
Response.ContentLength = contentLength;//在Response的Header中设置下载文件的大小,这样客户端浏览器才能正确显示下载的进度 byte[] buffer;
long hasRead = ;//变量hasRead用于记录已经发送了多少字节的数据到客户端浏览器 //如果hasRead小于contentLength,说明下载文件还没读取完毕,继续循环读取下载文件的内容,并发送到客户端浏览器
while (hasRead < contentLength)
{
//HttpContext.RequestAborted.IsCancellationRequested可用于检测客户端浏览器和ASP.NET Core服务器之间的连接状态,如果HttpContext.RequestAborted.IsCancellationRequested返回true,说明客户端浏览器中断了连接
if (HttpContext.RequestAborted.IsCancellationRequested)
{
//如果客户端浏览器中断了到ASP.NET Core服务器的连接,这里应该立刻break,取消下载文件的读取和发送,避免服务器耗费资源
break;
} buffer = new byte[bufferSize]; int currentRead = fs.Read(buffer, , bufferSize);//从下载文件中读取bufferSize(1024字节)大小的内容到服务器内存中 Response.Body.Write(buffer, , currentRead);//发送读取的内容数据到客户端浏览器
Response.Body.Flush();//注意每次Write后,要及时调用Flush方法,及时释放服务器内存空间 hasRead += currentRead;//更新已经发送到客户端浏览器的字节数
}
}
} return new EmptyResult();
}
}
}

ASP.NET Core下载大文件的实现的更多相关文章

  1. ASP.NET如何下载大文件

    关于此代码的几点说明: 1. 将数据分成较小的部分,然后将其移动到输出流以供下载,从而获取这些数据. 2. 根据下载的文件类型来指定 Response.ContentType .(参考OSChina的 ...

  2. ASP.Net 下载大文件的实现

    当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃.可以参考如下代码来避免这个问题. 关于此代码的几点说明: 1. 将数据分成较小的部分,然后将其移 ...

  3. ASP.Net 下载大文件的实现 (转)

    原文:http://www.cnblogs.com/luisliu/p/4253815.html 当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃 ...

  4. 基于 Vue.js 之 iView UI 框架非工程化实践记要 使用 Newtonsoft.Json 操作 JSON 字符串 基于.net core实现项目自动编译、并生成nuget包 webpack + vue 在dev和production模式下的小小区别 这样入门asp.net core 之 静态文件 这样入门asp.net core,如何

    基于 Vue.js 之 iView UI 框架非工程化实践记要   像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引 ...

  5. 转(Response.WriteFile 无法下载大文件解决方法)

    以前用Response.WriteFile(filename),但当遇到大文件时无法完整下载. 该方法最大的问题,它不是直接将数据抛到客户端,而是在服务器端(IIS)上缓存.当下载文件比较大时,服务器 ...

  6. ASP.NET Core 中的文件上传

    ASP.NET Core上传文件 ASP.NET Core使用IFormFile来读取上传的文件内容,然后将数据写入到磁盘或其它存储空间. 添加FileUpload模型,用来接收上传的文件内容. pu ...

  7. ASP.NET 中对大文件上传的简单处理

    在 ASP.NET 开发的过程中,文件上传往往使用自带的 FileUpload 控件,可是用过的人都知道,这个控件的局限性十分大,最大的问题就在于上传大文件时让开发者尤为的头疼,而且,上传时无法方便的 ...

  8. python下载大文件

    1. wget def download_big_file_with_wget(url, target_file_name): """ 使用wget下载大文件 Note: ...

  9. python 下载大文件

    当使用requests的get下载大文件/数据时,建议使用使用stream模式. 当把get函数的stream参数设置成False时,它会立即开始下载文件并放到内存中,如果文件过大,有可能导致内存不足 ...

随机推荐

  1. 在生产环境中安全执行更新删除SQL脚本的技巧

    今天在生产环境上解决问题,由于广发银行的管理制度是开发公司是不允许确生产环境的,所以我们只能把要更新的语句发给运营中心,由运营中心的投产人员执行,我们则在旁边看着:在他执行的时候发现了一个很有趣的技巧 ...

  2. Keras vs. PyTorch in Transfer Learning

    We perform image classification, one of the computer vision tasks deep learning shines at. As traini ...

  3. 整理JavaScript循环数组和对象的方法

    众所周知,常用的循环语句有for.while.do-while.for-in,forEach以及jQuery中提供的循环的方法:以及ES6中提供的很多用来循环对象的方法如map, 在 Javascri ...

  4. LeetCode题解之Multiply Strings

    1.题目描述 2.问题分析 按照手算乘法的过程进行计算,首先计算乘法,然后计算加法. 3.代码 string multiply(string num1, string num2) { string s ...

  5. LeetCode题解之Find the Difference

    1.题目描述 2.题目分析 比较两个字符串中加入的一个字符,由于可能在字符串中加入一个已经存在的字符,因此使用hash table 去统计字符个数最好. 3.代码 char findTheDiffer ...

  6. teradata 查询创建表的时间

    如何查询teradata创建表的时间? select tablename,CreateTimeStamp from dbc.tables ---dbc的table,user是在dbc内的吗?具体不清楚 ...

  7. SQL SERVER中的And与Or的优先级

    数据库中有城市库表,其中有国家.省.城市. 举例:在广东省内(包含广东省本身),找出名称为“广州”的记录 首先,广东省内的条件是:ParentId = 2 Or Id =2 名称为“广州”的条件是:N ...

  8. linux下yum安装指定的mysql版本

    因为直接使用yum安装的mysql会是默认版本5.1的版本  但是有的同学不满足又想要其他版本的怎么办呢? 曾时候我来提供一种方案(仅供参考): 我们可以使用rpm包来进行指定mysql版本的安装, ...

  9. iOS8 CIGlassDistortion滤镜的使用

    iOS8 CIGlassDistortion滤镜的使用 此为CoreImage滤镜的使用 素材 效果 混合用图片 源码: // // ViewController.m // CIGlass // // ...

  10. 静态代码分析工具sonarqube+sonar-runner的安装配置及使用

    配置成功后的代码分析页面: 可以看到对复杂度.语法使用.重复度等等都做了分析,具体到了每一个方法和每一句代码. 四种使用方式: sonarqube + sonar-runner sonarqube + ...