当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃。可以参考如下代码来避免这个问题。

  1. using System; 

  2. namespace WebApplication1 

  3.     public partial class DownloadFile : System.Web.UI.Page 

  4.     { 

  5.         protected void Page_Load(object sender, EventArgs e) 

  6.         { 

  7.             System.IO.Stream iStream = null

  8.             // Buffer to read 10K bytes in chunk: 

  9.             byte[] buffer = new Byte[10000]; 

  10.             // Length of the file: 

  11.             int length; 

  12.             // Total bytes to read. 

  13.             long dataToRead; 

  14.             // Identify the file to download including its path. 

  15.             string filepath = Server.MapPath("/") +"./Files/TextFile1.txt"

  16.             // Identify the file name. 

  17.             string filename = System.IO.Path.GetFileName(filepath); 

  18.             try 

  19.             { 

  20.                 // Open the file. 

  21.                 iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, 

  22.                             System.IO.FileAccess.Read, System.IO.FileShare.Read); 

  23.                 // Total bytes to read. 

  24.                 dataToRead = iStream.Length; 

  25.                 Response.Clear(); 

  26.                 Response.ClearHeaders(); 

  27.                 Response.ClearContent(); 

  28.                 Response.ContentType = "text/plain"// Set the file type 

  29.                 Response.AddHeader("Content-Length", dataToRead.ToString()); 

  30.                 Response.AddHeader("Content-Disposition""p_w_upload; filename=" + filename); 

  31.                 // Read the bytes. 

  32.                 while (dataToRead > 0

  33.                 { 

  34.                     // Verify that the client is connected. 

  35.                     if (Response.IsClientConnected) 

  36.                     { 

  37.                         // Read the data in buffer. 

  38.                         length = iStream.Read(buffer, 010000); 

  39.                         // Write the data to the current output stream. 

  40.                         Response.OutputStream.Write(buffer, 0, length); 

  41.                         // Flush the data to the HTML output. 

  42.                         Response.Flush(); 

  43.                         buffer = new Byte[10000]; 

  44.                         dataToRead = dataToRead - length; 

  45.                     } 

  46.                     else 

  47.                     { 

  48.                         // Prevent infinite loop if user disconnects 

  49.                         dataToRead = -1

  50.                     } 

  51.                 } 

  52.             } 

  53.             catch (Exception ex) 

  54.             { 

  55.                 // Trap the error, if any. 

  56.                 Response.Write("Error : " + ex.Message); 

  57.             } 

  58.             finally 

  59.             { 

  60.                 if (iStream != null

  61.                 { 

  62.                     //Close the file. 

  63.                     iStream.Close(); 

  64.                 } 

  65.                 Response.End(); 

  66.             } 

  67.         } 

  68.     } 

关于此代码的几点说明:

1. 将数据分成较小的部分,然后将其移动到输出流以供下载,从而获取这些数据。

2. 根据下载的文件类型来指定 Response.ContentType 。(参考OSChina的这个网址可以找到大部分文件类型的对照表:http://tool.oschina.net/commons)

3. 在每次写完response时记得调用 Response.Flush()

4. 在循环下载的过程中使用 Response.IsClientConnected 这个判断可以帮助程序尽早发现连接是否正常。若不正常,可以及早的放弃下载,以释放所占用的服务器资源。

5. 在下载结束后,需要调用 Response.End() 来保证当前线程可以在最后被终止掉。

原文链接: