HTTP 文件下载主要有两种方式:
URL方式直接下载,优点是:占用服务器资源少,速度快;缺点是: 不能准确计量下载次数,无法防止盗链,保存在数据库中的文件无法下载,常见格式的文件如.html 直接在浏览器中打开,不能直接下载。
二进制数据流输出方式,优点是:准确计量下载次数、能防盗链、所有文件格式都能直接下载而不是打开、保存在数据库中等非文件数据能以文件方式下载等;缺点是占用服务器资源多。
大文件下载原理是把文件切成小段数据流下载,微软msdn给出了大文件下载的示例,但存在中文文件名乱码问题,稍加改动即可。代码为:
01.
protected
void
ResponseFile(
string
path) {
02.
System.IO.Stream iStream =
null
;
03.
byte
[] buffer =
new
Byte[10000];
04.
int
length;
05.
long
dataToRead;
06.
string
filename = System.IO.Path.GetFileName(path);
07.
08.
try
{
09.
iStream =
new
System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
10.
dataToRead = iStream.Length;
11.
Response.ContentType =
"application/octet-stream"
;
12.
Response.AddHeader(
"Content-Disposition"
,
"attachment; filename="
+ HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8));
13.
while
(dataToRead > 0) {
14.
if
(Response.IsClientConnected) {
15.
length = iStream.Read(buffer, 0, 10000);
16.
Response.OutputStream.Write(buffer, 0, length);
17.
Response.Flush();
18.
buffer =
new
Byte[10000];
19.
dataToRead = dataToRead - length;
20.
}
21.
else
{
22.
dataToRead = -1;
23.
}
24.
}
25.
}
26.
catch
(Exception ex) {
27.
Response.Write(
"文件下载时出现错误!"
);
28.
}
29.
finally
{
30.
if
(iStream !=
null
) {
31.
iStream.Close();
32.
}
33.
}
34.
}
2.防止盗链
01.
protected
void
Page_Load(
object
sender, EventArgs e) {
02.
/*-------------大文件下载,防盗链------------------*/
03.
if
(Request.QueryString[
"FileName"
] ==
null
) { InvalidRedirect(); }
04.
string
fileName = Request.QueryString[
"FileName"
];
05.
if
(fileName ==
string
.Empty) { InvalidRedirect(); }
06.
//判断配置文件是否直接下载
07.
string
downDirect = ConfigurationManager.AppSettings[
"Down"
].ToLower();
08.
if
(downDirect ==
"true"
) { UpdateHits(fileName);
09.
//更新下载次数 Response.Redirect("Upload/" + fileName); return; }
10.
string
path = Server.MapPath(Request.ApplicationPath +
"/Upload/"
+ fileName);
11.
string
referrer =
string
.Empty;
12.
if
(Request.UrlReferrer !=
null
) { referrer = Request.UrlReferrer.ToString().ToLower(); }
13.
string
d = ConfigurationManager.AppSettings[
"Valid"
].ToLower();
14.
string
[] domainName = ConfigurationManager.AppSettings[
"Refers"
].ToLower().Split(
new
char
[] {
','
});
15.
// 如果设置为防止盗链,判断访问来源是否合法
16.
if
(d ==
"false"
) {
17.
foreach
(
string
s
in
domainName) {
18.
if
(referrer.IndexOf(s.ToLower()) > 0) { UpdateHits(fileName);
19.
//更新下载次数
20.
ResponseFile(path);
21.
return
;
22.
}
23.
}
24.
InvalidRedirect();
25.
}
26.
else
{
27.
ResponseFile(path);
28.
}
29.
}
30.
protected
void
UpdateHits(
string
fileName) {
31.
//更新文件下载次数的代码
32.
}
33.
protected
void
InvalidRedirect() {
34.
string
defaultPage = ConfigurationManager.AppSettings[
"DefaultRedirect"
];
35.
Response.Redirect(defaultPage,
true
);
36.
}
3.配置文件
配置文件中配置下载方式、盗链功能是否开启及盗链默认转向的页面地址:
01.
<appSettings>
02.
<add key=
"Down"
value=
"false"
/>
03.
<!--是否直接下载-->
04.
<add key=
"Valid"
value=
"false"
/>
05.
<!--是否允许盗链-->
06.
<add key=
"Refers"
value=
"localhost,google.cn"
/>
07.
<!--多个允许的访问来源用半角的
","
分割-->
08.
<add key=
"DefaultRedirect"
value=
"Error.htm"
/>
09.
<!--默认转向的页面-->
10.
</appSettings>