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

ASP.NET 檔案下載六種實作方式完整比較:從 TransmitFile 到分塊串流

     編輯:ASP.NET 基礎

核心 HTTP 標頭設定(所有方式通用)

Response.ContentType = "application/octet-stream"; // 或具體 MIME
Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
Response.AddHeader("Content-Length", fileSize.ToString()); // 若可預知

方式一:Response.TransmitFile(推薦大檔案)

Response.TransmitFile(filePath); // 直接由 IIS 核心模式傳送,不經 ASP.NET 記憶體
Response.End();
  • 優點:不佔用 Managed Heap 記憶體、支援 >2GB 檔案、IIS 核心快取、自動處理斷點續傳(Range 標頭)。
  • 適用:生產環境大檔案下載首選。

方式二:Response.WriteFile(簡單易用)


Response.Clear();
Response.WriteFile(filePath);
Response.Flush();
Response.End();
  • 內部同樣使用 TransmitFile,但會先載入檔案資訊,中型檔案適用。

方式三:Response.WriteFile 分塊讀取(控制記憶體)


const int ChunkSize = 102400; // 100KB
byte[] buffer = new byte[ChunkSize];
using (FileStream fs = File.OpenRead(filePath))
{
    long remaining = fs.Length;
    while (remaining > 0 && Response.IsClientConnected)
    {
        int read = fs.Read(buffer, 0, ChunkSize);
        Response.OutputStream.Write(buffer, 0, read);
        Response.Flush();
        remaining -= read;
    }
}
Response.Close();
  • 優點:固定緩衝區,記憶體佔用恆定,適合超大檔或高併發。
  • 關鍵:檢查 Response.IsClientConnected 避免用戶取消後繼續佔用資源。

方式四:FileStream + BinaryWrite(傳統完整讀取)


byte[] bytes = File.ReadAllBytes(filePath); // 一次性載入記憶體!
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
  • 缺點:大檔案易導致 OutOfMemoryException、LOT(大物件堆)碎片化、**不推薦生產環境使用**。

方式五:FileStream 手動分塊寫入 OutputStream(精細控制)


using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    byte[] buffer = new byte[81920]; // 80KB
    int bytesRead;
    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0 && Response.IsClientConnected)
    {
        Response.OutputStream.Write(buffer, 0, bytesRead);
        Response.Flush();
    }
}
  • 與方式三類似,但使用 FileShare.Read 允許其他程序同時讀取。

方式六:MVC FileResult / ASP.NET Core PhysicalFileResult(現代化)


// ASP.NET MVC
return File(filePath, "application/octet-stream", fileName);

// ASP.NET Core
return PhysicalFile(filePath, "application/octet-stream", fileName); // 自動支援 Range、ETag、快取
  • 框架層級封裝,自動處理 Range 請求、快取標頭、非同步傳輸,**新專案首選**。

比較總結表

方式記憶體大檔案斷點續傳複雜度推薦指數
TransmitFile極低✅ 最佳✅ IIS 原生低⭐⭐⭐⭐⭐
WriteFile低✅❌低⭐⭐⭐⭐
分塊 WriteFile固定低✅❌ 需自行處理 Range中⭐⭐⭐⭐
BinaryWrite 全讀高 (OOM 風險)❌❌低⭐
手動 FileStream固定低✅❌ 需自行處理中⭐⭐⭐
FileResult / PhysicalFile極低✅ 最佳✅ 框架自動極低⭐⭐⭐⭐⭐

實務建議

  1. **舊版 Web Forms**:優先 TransmitFile,極大檔或需自訂邏輯用分塊。
  2. **MVC 5**:使用 File() 回傳 FilePathResult。
  3. **ASP.NET Core**:直接 PhysicalFile() 或 FileStreamResult,支援非同步 FileStreamResultAsync。
  4. **安全性**:檔案路徑嚴格驗證,防止路徑遍歷攻擊;Content-Disposition 檔名務必 UrlEncode。
  5. **效能**:啟用 IIS 靜態內容快取、輸出快取;CDN 分發大型公開檔案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved