/*
* asp.net 几种文件下载方式比较
*
* 方法1、HttpResponse.TransmitFile
* 方法2、HttpResponse.WriteFile
* 方法3、HttpResponse.BinaryWrite
* 方法4、HttpResponse.Redirect
*
* 方法1与方法2
* 相同点:都是通过文件的相对或绝对路径下载文件;
* 不同点:方法2是一次性将文件读入内存,然后输出给客户端;
* 方法1不在内存中缓冲文件。
*
* 因此,对于大文件或用户数多的下载,方法1不会对于服务器内存的占用将远远低于方法2;
* 这正是方法1的最大优势,
* 但方法1也有一个局限:does not work with UNC-share file paths. *
* UNC (Universal Naming Convention) / 通用命名规则,也叫通用命名规范、通用命名约定。
* 它符合 \servername\sharename 格式
* 也就是说方法1无法下载网络共享磁盘的文件
*
* 例如:
* if (filePath.StartsWith(@"\\"))
* context.Response.WriteFile(filePath, false);
* else
* context.Response.TransmitFile(filePath);
*
* 方法3
* 方法3主要是将已有的btye[] 型对象输出到客户端;
* 如果要下载的文件位于数据库等存储介质,那么,读入内存时一般可放于DataTable等对象中,
* 这时就可以直接HttpResponse.BinaryWrite((byte[])dt.Rows[0]["fileContent"])输出
*
* 方法4
* 方法4主要是通过文件的相对路径下载文件; *
*
*
* 以上四个方法,如果下载一个汉字命名且字数超过20个字的文件
* 方法1不会有问题;
* 使用其它三个方法下载后,如果客户端在提示框中点“打开”将报错,提示文件名过长。
*
*/ 以下是测试用到的 download.aspx 及 download.cs的代码:
download.aspx

Code

<%
@ Page Language="C#" AutoEventWireup="true" CodeFile="download.aspx.cs" Inherits="download" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div> <asp:Button ID="btnDownloadByRedirect" runat="server"
Text="using Response.Redirect()" onclick="btnDownloadByRedirect_Click"
/>
<asp:Button ID="btnDownloadByTransmitFile" runat="server" Text="using Response.TransmitFile()"
onclick="btnDownloadByTransmitFile_Click" />
<asp:Button ID="btnDownloadByWriteFile" runat="server" Text="using Response.WriteFile()"
OnClick="btnDownloadByWriteFile_Click" />
<asp:Button ID="btnDownloadByBinaryWrite" runat="server" Text="using Response.BinaryWrite()"
OnClick="btnDownloadByBinaryWrite_Click" />
</div>
</form>
</body>
</html>

download.cs

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Text;

public partial class download : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)

{
//System.Threading.Thread.Sleep(5000);
//Download(HttpContext.Current.Response);
}

protected void btnDownloadByRedirect_Click(object sender, EventArgs e)

{
Download(HttpContext.Current.Response);
}

protected void btnDownloadByTransmitFile_Click(object sender, EventArgs e)

{
Download(HttpContext.Current.Response, DownloadMethod.TransmitFile);
}

protected void btnDownloadByWriteFile_Click(object sender, EventArgs e)

{
Download(HttpContext.Current.Response, DownloadMethod.WriteFile);
}

protected void btnDownloadByBinaryWrite_Click(object sender, EventArgs e)

{
Download(HttpContext.Current.Response, DownloadMethod.BinaryWrite);
}

private FileInfo info = null;

private enum DownloadMethod

{
WriteFile,
BinaryWrite,
TransmitFile
}

private bool PrepareFile()

{
string applicationPath = HttpContext.Current.Request.PhysicalApplicationPath;
string lastCharacter = applicationPath.Substring(applicationPath.Length - 1);

if (!lastCharacter.Equals("\\"))

{
applicationPath = applicationPath + "\\";
}

info = new FileInfo(applicationPath + "Files\\测试文件测试文件测试文件测试文件测试文件测.xls");

return info.Exists;
}

private byte[] GetFileByte()

{
return File.ReadAllBytes(info.FullName);
}

private long GetFileLength()

{
return info.Length;
}

private void Download(HttpResponse response)

{
if (PrepareFile())

{
response.Redirect("Files/" + info.Name, true);
}
}

private void Download(HttpResponse response, DownloadMethod method)

{
if (PrepareFile())

{
response.Clear();
response.ClearHeaders();
response.Buffer = false;

string displayName = HttpUtility.UrlEncode(Encoding.UTF8.GetBytes(info.Name));

response.AppendHeader("Content-Disposition", "attachment;filename=" + displayName);
response.ContentType = "application/octet-stream";

switch (method)

{
case DownloadMethod.WriteFile:
//response.WriteFile(info.FullName);
response.TransmitFile("Files/" + info.Name);
break;

case DownloadMethod.BinaryWrite:
response.BinaryWrite(GetFileByte());
break;

case DownloadMethod.TransmitFile:
//response.TransmitFile(info.FullName);
response.TransmitFile("Files/" + info.Name);
break;
}

response.Flush();
response.End();
}
}