在Asp.net中提供了几种下载方式下载文件。
一、直接将文件的地址返回给客户端
服务器直接将文件的地址返回给客户端,客户端直接链接到服务器文件。缺点是暴露了文件的地址,同时有些文件浏览器直接打开,如.txt,.jpg等格式文件,浏览器可直接打开。
二、使用WriteFile方式下载文件
该方案缺陷是使用WriteFile下载大文件时占用服务器内存较大,加大服务器压力
void DownFile(string filePath,string fileName)
{
System.IO.FileInfo fileInfo=new FileInfo(filePath);
//清空Response中的缓存,输出头部信息
Response.Clear();
Response.ClearHeader()
Response.ClearContent();
//attachment强制浏览器下载
Response.AddHeader("Content-Disposition","attachment;filename="+fileName);
Response.AddHeader("Content-Length",fileInfo.Length.ToString());
Response.AddHeader("Content-Transfer-Encoding","binary");
//ContentType可用xml文件进行动态配置,根据文件后缀名动态配置ContentType
Response.ContentType="application/octet-stream";
Response.ContentEncoding=System.Text.Encoding.GetEncoding("Gb2312");
Response.WriteFile(fileInfo.FullName);
Response.Flush();//输出缓存
Response.End();
}
三、使用WriteFile方法分块下载文件
该方案将文件分块加载到内存中,当读取相应大小的文件后,及时使用Response.Flush()方法输出缓存,之后继续读取下一块文件
void DownLoadFile(string filePath,string fileName)
{
System.IO.FileInfo fileInfo=new System.IO.FileInfo(filePath);
if(fileInfo.Exists)
{
const long ChunkSize=102400;//每次加载100kb数据
byte[] buffer=new byte[ChunkSize];
Response.Clear();
System.IO.FileStream iStream=System.IO.File.OpenRead(filePath);//建立流对象
long dataLengthToRead=iStream.Length;//获取文件总大小
//ContentType可用xml文件进行动态配置,根据文件后缀名动态配置ContentType
Response.ContentType="application/octet-stream";
Response.AddHeader("Content-Disposition","attachment;filename="+HttpUtility.UrlEncode(fileName));
Response.AddHeader("Content-Length",fileInfo.Length.ToString());
while(dataLengthToRead>0&&Response.IsClientConnected)
{
int lengthRead=iStream.Read(buffer,0,Convert.ToInt32(ChunkSize);
Response.OutputStream.Write(buffer,0,lengthRead);
Response.Flush();
dataLengthToRead=dataLengthToRead-lengthRead;
}
iStream.Close();
Response.End();//此处网上很多用Response.Close强行关闭连接,但我在mvc项目中用 Response.Close()总抛出"无法在头信息后添加内容信息",有谁知道请指教为何。
}
}
四、使用Response.BinaryWrite方式下载
void DownLoadFile(string filePath,string fileName)
{
System.IO.FileStream iStream=System.IO.File.OpenRead(filePath);//建立流对象
long length=iStream.Length;
byte[] bytes=new byte[length];
iStream.Read(bytes,0,bytes.Length);
iStream.Close();
Response.AddHeader("Content-Disposition","attachment;filename="+HttpUtility.UrlEncode(fileName));
Response.BinaryWrite(bytes);
Response.Flush();
Rsponse.End();
}
五、此外还可以使用Response.TransmitFile下载文件,此方法可以解决使用Response.BinaryWrite
下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。
如果你使用MVC,还可以直接放回一个FileResult动作实现下载功能