首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 檔案下載:Response.BinaryWrite 直接輸出檔案串流

     編輯:關於ASP.NET

常見誤區:window.open 下載

string js = "";
Response.Write(string.Format(js, url));

缺點:被彈出視窗攔截器擋截、無法控制檔案名、無法驗證權限、大檔案記憶體壓力大。

標準做法:BinaryWrite 輸出串流

protected void DownloadFile(string physicalPath)
{
 // 1. 取得檔案資訊
 FileInfo file = new FileInfo(physicalPath);
 if (!file.Exists) { Response.StatusCode = 404; return; }

 // 2. 設定回應標頭
 Response.Clear();
 Response.ClearHeaders();
 Response.Buffer = false; // 關閉緩衝,直接串流輸出,大檔案不佔記憶體
 Response.ContentType = "application/octet-stream"; // 通用二進位,強制下載
 Response.AddHeader("Content-Disposition", $"attachment; filename=\"{HttpUtility.UrlEncode(file.Name, Encoding.UTF8)}\"");
 Response.AddHeader("Content-Length", file.Length.ToString());
 Response.AddHeader("Content-Transfer-Encoding", "binary");

 // 3. 分塊讀取並輸出 (避免大檔案一次性載入記憶體)
 const int bufferSize = 1024 * 64; // 64KB
 byte[] buffer = new byte[bufferSize];
 long sent = 0;

 using (FileStream fs = new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read))
 {
 while (sent < file.Length && Response.IsClientConnected)
 {
 int read = fs.Read(buffer, 0, bufferSize);
 if (read == 0) break;
 Response.OutputStream.Write(buffer, 0, read);
 Response.Flush(); // 立即發送給客戶端
 sent += read;
 }
 }

 // 4. 結束回應
 Response.End(); // 或 HttpContext.Current.ApplicationInstance.CompleteRequest();
}

關鍵點解析

設定用途
Content-Disposition: attachment強制瀏覽器彈出「另存新檔」對話框,而非直接開啟
filename 編碼 (UrlEncode + UTF-8)支援中文檔名,避免亂碼 (RFC 5987 進階編碼更佳)
Content-Length讓瀏覽器顯示下載進度、支援斷點續傳 (需配合 Range 請求)
Buffer = false + Flush串流模式,記憶體佔用恆定 (約 bufferSize),適合 GB 級大檔
Response.IsClientConnected偵測使用者取消下載,提早釋放資源
FileShare.Read允許同時多使用者下載同一檔案

進階:支援斷點續傳 (Range Requests)


// 在輸出前檢查 Request.Headers["Range"]
// 回應 206 Partial Content、Content-Range、Accept-Ranges: bytes
// 實作較複雜,建議使用成熟庫或 IIS 靜態檔案處理 (配合授權模組)

安全性檢查清單

  • 驗證使用者權限 (登入、角色、檔案擁有者)。
  • 防止路徑遍歷攻擊:`Path.GetFullPath` 對比允許根目錄。
  • 記錄下載日誌 (使用者、檔案、時間、IP、完成/中斷)。
  • 限制同時下載數、頻寬節流 (大檔案/付費內容)。

替代方案

  • IIS 靜態檔案 + URL 授權:將檔案放在受保護目錄,`` 設定權限,IIS 直接傳送 (效能最好、支援 Range/快取)。
  • VirtualPathProvider:虛擬路徑對應至資料庫/雲端儲存。
  • ASP.NET Core `FileResult` / `PhysicalFileResult`:內建支援 Range、ETag、串流。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved