您的位置:首页 > 编程语言 > ASP

ASP.NET 中如何通过编码的方式限制文件的下载速度

2012-07-28 00:01 686 查看
有时候,在处理客户端请求下载文件时,为了避免服务器一次缓冲一个大文件到内存,然后发给客户端来下载,常常需要禁用服务器端的缓冲,一点一点地发送给客户端,这样的好处是不用占用大多的服务器内存,万一客户端终止下载,也可以随时停止响应。

废话不多说,直接贴代码了:

前台代码:

<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;
}
}

}
}
}
}


谢谢浏览!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐