C# 大文件分块下载
Http 协议中有专门的指令来告知浏览器, 本次响应的是一个需要下载的文件. 格式如下:
Content-Disposition: attachment;filename=filename.ext
以上指令即标记此次响应流是附件,且附件文件名为 filename.ext。
文件下载方式:
protected void Page_Load(object sender, EventArgs e) { Response.WriteFile("Tree.jpg"); Response.Flush(); Response.Close(); } protected void Page_Load(object sender, EventArgs e) { Response.BinaryWrite(File.ReadAllBytes(Server.MapPath("Tree.jpg"))); Response.Flush(); Response.Close(); } protected void Page_Load(object sender, EventArgs e) { int chunkSize = 64; byte[] buffer = new byte[chunkSize]; int offset = 0; int read = 0; using (FileStream fs = File.Open(Server.MapPath("Tree.jpg"), FileMode.Open, FileAccess.Read, FileShare.Read)) { while ((read = fs.Read(buffer, offset, chunkSize)) > 0) { Response.OutputStream.Write(buffer, 0, read); Response.Flush(); } } Response.Close(); }
1.分块下载服务器物理路径下的文件
/// <summary> /// 使用OutputStream.Write分块下载文件 /// </summary> /// <param></param> public void WriteFileBlock(string filePath) { filePath = Server.MapPath(filePath); if (!File.Exists(filePath)) { return; } FileInfo info = new FileInfo(filePath); //指定块大小 long chunkSize = 4096; //建立一个4K的缓冲区 byte[] buffer = new byte[chunkSize]; //剩余的字节数 long dataToRead = 0; FileStream stream = null; try { //打开文件 stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); dataToRead = stream.Length; //添加Http头 HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.AddHeader("Content-Disposition", "attachement;filename=" + Server.UrlEncode(info.FullName)); HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString()); while (dataToRead > 0) { if (HttpContext.Current.Response.IsClientConnected) { int length = stream.Read(buffer, 0, Convert.ToInt32(chunkSize)); HttpContext.Current.Response.OutputStream.Write(buffer, 0, length); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.Clear(); dataToRead -= length; } else { //防止client失去连接 dataToRead = -1; } } } catch (Exception ex) { HttpContext.Current.Response.Write("Error:" + ex.Message); } finally { if (stream != null) { stream.Close(); } HttpContext.Current.Response.Close(); } }
2.使用WebClient下载http文件到客户端。分块下载,防止大文件下载阻塞浏览器。
Response.Flush和Response.BufferOutput
Response.Flush方法用来将缓冲区的数据立即输出到浏览器当中。你可以多次调用Response.Flush 方法,,当这样使用时,浏览器将多次接受数据,而不是仅接受一次数据。
Response.BufferOutput是一个布尔值,指示是否缓冲输出并在整个页面在服务器端处理完毕后才发送缓冲区中的数据。true是其默认值。
服务器端是否缓存数据取决于Response.BufferOutput,当你将Response.BufferOutput的值设为true时,数据会缓存到buffer中,并在页面处理完毕后,将buffer中的内容一次性全部发到客户端。如果为false,则不缓冲数据,每执行一个response.write方法,数据就会立即发往客户端,数据的传送次数取决于你使用了多少个response.write方法,在这种情况下,使用response.Flush方法是没有意义的。只用当你将Response.BufferOutput属性的值设为true时,使用response.Flush方法才有意义。这时服务器端会将调用response.Flush方法时之前的所有response.write方法的数据发往客户端。
只要将Response.BufferOutput的值设置为true,一定会发送buffer里的内容,只是早晚、次数的问题,这就取决于Response.Flush方法了。
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/64882.html