// 输出硬盘文件,提供下载
// 输入参数 _Request: Page.Request对象, _Response: Page.Response对象, _fileName: 下载文件名, _fullPath: 带文件名下载路径, _speed 每秒允许下载的字节数
// 返回是否成功
public static bool ResponseFile(HttpRequest _Request,HttpResponse _Response,string _fileName,string _fullPath, long _speed)
{
try
{
FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(myFile);
try
{
_Response.AddHeader("Accept-Ranges", "bytes");
_Response.Buffer = false;
long fileLength = myFile.Length;
long startBytes = 0;
int pack = 10240; //10K bytes
//int sleep = 200; //每秒5次 即5*10K bytes每秒
int sleep = (int)Math.Floor(1000 * pack / _speed) + 1;
if (_Request.Headers["Range"] != null)
{
_Response.StatusCode = 206;
string[] range = _Request.Headers["Range"].Split(new char[] {'=', '-'});
startBytes = Convert.ToInt64(range[1]);
}
_Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
if (startBytes != 0)
{
_Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength-1, fileLength));
}
_Response.AddHeader("Connection", "Keep-Alive");
_Response.ContentType = "application/octet-stream";
_Response.AddHeader("Content-Disposition","attachment;filename=" + HttpUtility.UrlEncode(_fileName,System.Text.Encoding.UTF8) );
br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
int maxCount = (int) Math.Floor((fileLength - startBytes) / pack) + 1;
for (int i = 0; i < maxCount; i++)
{
if (_Response.IsClientConnected)
{
_Response.BinaryWrite(br.ReadBytes(pack));
Thread.Sleep(sleep);
}
else
{
i=maxCount;
}
}
}
catch
{
return false;
}
finally
{
br.Close();
myFile.Close();
}
}
catch
{
return false;
}
return true;
}
调用例
Page.Response.Clear();
bool success = ResponseFile(Page.Request, Page.Response, "filename", @"C:\download.date", 1024000);
if(!success)
Response.Write("下载文件出错!");
Page.Response.End();
作者Blog:javascript:void(0)
下面是vb.net 版本
Public Function ResponseFile(ByVal FRequest As HttpRequest, ByVal FResponse As HttpResponse, ByVal fileName As String, ByVal fullPath As String, ByVal speed As Long) As Boolean
Try
Dim myFile As FileStream = New FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Dim br As BinaryReader = New BinaryReader(myFile)
Try
FResponse.AddHeader("Accept-Ranges", "bytes")
FResponse.Buffer = False '關閉存後送出
Dim fileLength As Long = myFile.Length
Dim startBytes As Long = 0
Dim pack As Integer = 10240 '10K bytes
'int sleep = 200; //每秒5次 即5*10K bytes每秒
Dim sleep As Integer = CType(Math.Floor(1000 * pack / speed) + 1, Integer)
If (FRequest.Headers("Range") <> Nothing) Then
FResponse.StatusCode = 206
Dim range() As String = FRequest.Headers("Range").Split(New Char() {"="c, "-"c})
startBytes = Convert.ToInt64(range(1))
End If
FResponse.AddHeader("Content-Length", (fileLength - startBytes).ToString())
If (startBytes <> 0) Then
FResponse.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength))
End If
FResponse.AddHeader("Connection", "Keep-Alive")
FResponse.ContentType = "application/octet-stream"
FResponse.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8))
br.BaseStream.Seek(startBytes, SeekOrigin.Begin)
Dim maxCount As Integer = CType(Math.Floor((fileLength - startBytes) / pack) + 1, Integer)
Dim i As Integer
For i = 0 To maxCount - 1 Step i + 1
If (FResponse.IsClientConnected) Then
FResponse.BinaryWrite(br.ReadBytes(pack))
Thread.Sleep(sleep)
Else
i = maxCount
End If
Next
Catch
Return False
Finally
br.Close()
myFile.Close()
End Try
Catch
Return False
End Try
Return True
End Function
調用時:
Page.Response.Clear()
Me.ResponseFile(Page.Request, Page.Response, filename, Server.MapPath(fileurl), 10240)
Page.Response.End()