如何下载任何文件






1.40/5 (10投票s)
2007 年 6 月 14 日
3分钟阅读

37191
在本文中,我将尝试解释如何构建一个简单的Web用户控件来处理任何类型的文件下载,甚至包括HTML文件。
引言
也许有些人会说这是老生常谈,并且有数百篇类似的文章,但也许是真的,但我发现的说法一般没有详细说明如何处理从服务器下载的Unicode文件,或者多段文件名问题,尤其是Firefox浏览器,这会引起很多问题。
背景
在过去的几天里,我为一个部门得到了一个Web项目,该项目包含下载部分,为公众和网站成员提供文件下载,但存在一个小问题,即他们有时会上载不同格式的文件到网站上,因此对于像htm、txt这样的文件,会遇到一个小问题,例如,它们会直接在浏览器窗口中打开,这对于下载部分来说不是一个好主意。然后我决定构建一个Web用户控件,以强制在任何浏览器网站打开时打开保存对话框,我想向您提供一些有用的信息。
我也会尽量关注我在开发这个Web用户控件期间遇到的一些问题。
使用代码
我希望每个人都可以使用任何Microsoft .NET IDE将新的用户控件添加到他们自己的Web项目中。在添加此控件并将其命名为FileDownload
之后,我们将进入代码隐藏页面,因为我们不需要控件的GUI表示。
在我们的控件内部,我们应该指定几个系统常量和成员变量
private const string filesFolder = "~/docs/";
//不要使用硬编码,不推荐
private long fileSize = 0;
private int fileID = 0;
我将使用硬编码文件以方便理解,现在之后我们将进入Load
事件来处理查询字符串,该字符串包含用户希望从我们的网站下载的文件id。
protected void Page_Load(object sender, EventArgs e)
{
//检查是否设置了查询字符串,包含我们的文件id,以及该文件id的整数值
if(Request.QueryString.Count > 0 && Request.QueryString["fid"] != null && int.TryParse(Request.QueryString["fid"], out fileID) )
{
//检查后,我们从数据库中获取我们的文件信息,例如以下数据 [文件标题,服务器上的文件名]
//清除缓冲区流的所有内容输出
Response.Clear();
//清除响应提交的所有标头
Response.ClearHeader();
Response.ClearContent();
//添加新的页面标头以允许打开保存对话框
//我们在这里设置用户下载文件的文件名,作为标题,并将空格替换为(_)并删除任何其他特殊字符,因为它们都会导致firefox出现问题
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileCaption.Replace(" ","_").Trim("'!@#$%^&*()_+".ToCharArray()) + FileNameOnServerName.Substring(file.Name.LastIndexOf(".")));
//映射文件路径以将路径加载到对话框流中
string filePath = Server.Map(filesFolder + FileNameOnServer);
//现在我们创建一个流对象来获取有关文件的一些信息,例如文件大小
System.IO.FileStream stream = null;
try {
stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open);
fileSize = stream.Length;
Response.AddHeader("Content-Length", fileSize.ToString());
Response.ContentType = "application/octet-stream";
}
catch {}
finally
{
if ( stream != null )
stream.Close();
}
//现在将文件数据传递到响应中
try {
Response.WriteFile(filePath, 0, fileSize);
}catch{System.IO.Exception){}
Response.End();
}
在设置此代码之后,我们现在可以在任何页面中使用此控件,以便我们可以处理任何浏览器类型的文件下载。