ASP.NET 中如何通过编码的方式限制文件的下载速度
2012-07-28 00:01 音乐让我说 阅读(477) 评论(0) 编辑 收藏 举报有时候,在处理客户端请求下载文件时,为了避免服务器一次缓冲一个大文件到内存,然后发给客户端来下载,常常需要禁用服务器端的缓冲,一点一点地发送给客户端,这样的好处是不用占用大多的服务器内存,万一客户端终止下载,也可以随时停止响应。
废话不多说,直接贴代码了:
前台代码:
<form id="form1" runat="server"> <div> 请选择下载速度: <asp:DropDownList ID="ddlDonwloadSpeed" runat="server"> <asp:ListItem Value="20">20 Kb/s</asp:ListItem> <asp:ListItem Value="50">50 Kb/s</asp:ListItem> <asp:ListItem Value="80">80 Kb/s</asp:ListItem> </asp:DropDownList> <asp:Button ID="btnDownload" runat="server" Text="开始下载" OnClick="btnDownload_Click" /> </div> </form>
后台代码:
public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { GenerateFile(); } } /// <summary> /// 在服务器上生成一个 dat 文件 /// </summary> protected void GenerateFile() { int length = 1024 * 1024 * 1; // 1024 * 1024 * 1 = 1 Mb byte[] buffer = new byte[length]; string filepath = Server.MapPath("~/bigFileSample.dat"); using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write)) { fs.Write(buffer, 0, length); } } /// <summary> /// 下载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnDownload_Click(object sender, EventArgs e) { string outputFileName = "bigFileSample.dat"; string filePath = Server.MapPath("~/bigFileSample.dat"); string value = ddlDonwloadSpeed.SelectedValue; // 1024 * 20 = 20 Kb/s. int downloadSpeed = 1024 * int.Parse(value); Response.Clear(); try { DownloadFileWithLimitedSpeed(outputFileName, filePath, downloadSpeed); } catch (Exception ex) { Response.Write(@"<p><font color=""red"">"); Response.Write(ex.Message); Response.Write(@"</font></p>"); } Response.End(); } /// <summary> /// 处理下载业务 /// </summary> /// <param name="fileName">文件名</param> /// <param name="filePath">文件的路径</param> /// <param name="downloadSpeed">下载速度</param> public void DownloadFileWithLimitedSpeed(string fileName, string filePath, long downloadSpeed) { if (!File.Exists(filePath)) { throw new Exception("错误,这里没有文件供下载!"); } using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BinaryReader br = new BinaryReader(fs)) { //获取或设置一个值,该值指示是否缓冲输出并在处理完整个响应之后发送它 //我们不使用缓冲 Response.Buffer = false; long fileLength = fs.Length; // 包的最小大小为 1024 = 1 Kb. int pack = 1024; // 最初的公式: sleep = 1000 / (downloadspeed / pack) // 等同于: 1000.0 * pack / downloadSpeed. // 这里还有 1000 毫秒的停顿: 1000 millisecond = 1 second int sleep = (int)Math.Ceiling(1000.0 * pack / downloadSpeed); Response.AddHeader("Content-Length", fileLength.ToString()); Response.ContentType = "application/octet-stream"; string utf8EncodingFileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8); Response.AddHeader("Content-Disposition", "attachment;filename=" + utf8EncodingFileName); int maxCount = (int)Math.Ceiling(Convert.ToDouble(fileLength) / pack); for (int i = 0; i < maxCount; i++) { if (Response.IsClientConnected) { Response.BinaryWrite(br.ReadBytes(pack)); // 这里如果不停顿,则下载会以最大的速度下载。 Thread.Sleep(sleep); } else { break; } } } } } }
谢谢浏览!
作者:音乐让我说(音乐让我说 - 博客园)
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。