Transfer-Encoding:chunked 定義數據的包體部分爲分塊傳輸。
包體定義爲:
-------------------------------------------------------------------------------------
16進制長度\r\n
內容區(字節)\r\n
16進制長度\r\n
內容區(字節)\r\n
0\r\n //標識分塊結束,最後一塊長度爲0字節
\r\n //內容空行
\r\n //包體結束空行
-------------------------------------------------------------------------------------
實現如下:
/// <summary>
/// 以文件形式響應/// </summary>
/// <param name="httpContext">當前請求的上下文</param>
/// <param name="localfile">需要下載的文件</param>
/// <param name="fileName">下載後文件的名稱,爲空時,默認爲 localfile 的文件名</param>
public static void DoResponseFile(HttpContext httpContext,string localfile,string fileName = null)
{
HttpResponse resp = httpContext.Response;
try
{
fileName = string.IsNullOrEmpty(fileName) ? FS.GetFileNameFromFilePathName(localfile) : fileName;
using (FileStream fs = File.OpenRead(localfile))
{
resp.ClearContent();
resp.ContentType = "application/octet-stream";
resp.AppendHeader("Content-Transfer-Encoding", "binary");
resp.Headers.Add("Content-Disposition", "attachment;filename=" + default2utf8string(httpContext, fileName));
resp.Headers.Add("Transfer-Encoding", "chunked");
byte[] bts = new byte[4096];
using (BinaryReader br = new BinaryReader(fs, System.Text.Encoding.UTF8))
{
int n = 0;
while ((n = br.Read(bts, 0, bts.Length)) > 0)
{
byte[] bbss = Encoding.UTF8.GetBytes(n.ToString("x") + "\r\n");
resp.OutputStream.Write(bbss, 0, bbss.Length);
resp.OutputStream.Write(bts, 0, n);
resp.OutputStream.Write(new byte[] { 13, 10 }, 0, 2);
resp.Flush();
}
byte[] bbss2 = Encoding.UTF8.GetBytes("0\r\n\r\n");
resp.OutputStream.Write(bbss2, 0, bbss2.Length);
}
}
}
catch (Exception ex)
{
resp.ClearContent();
resp.Write(ex);
}
resp.End();
}
private static string default2utf8string(HttpContext httpContext, string fileName)
{
string btype = httpContext.Request.Browser.Type.ToLower();
if (btype.IndexOf("firefox") >= 0)
{
byte[] bts = Encoding.UTF8.GetBytes(fileName);
return string.Format("=?UTF-8?B?{0}?=", Convert.ToBase64String(bts));
}
else
return httpContext.Server.UrlEncode(fileName);
}