PRB: response.WriteFile 無法下載大型檔案

文章翻譯 文章翻譯
文章編號: 812406 - 檢視此文章適用的產品。
注意事項
本文中討論的協力廠商產品是由與 Microsoft 無關的公司所製造。Microsoft 可讓不以暗示或其他方式,效能或可靠性這些產品的保證。
全部展開 | 全部摺疊

在此頁中

徵狀

當您嘗試使用 Response.WriteFile 方法下載大型檔案時,下載可能不會回應,而且然後可能會收到下列錯誤訊息之一:
無法顯示該網頁
-或者-
伺服器應用程式無法使用

您嘗試存取這個 Web 伺服器上的 Web 應用程式是目前無法使用。請按 [重新整理] 按鈕,在您的網頁瀏覽器,以重試您的要求。

系統管理員注意事項: 錯誤訊息詳細說明此特定要求失敗的原因可以找到 Web 伺服器的系統事件日誌中。請檢閱這個記錄檔項目,以找出發生此錯誤的原因。
應用程式事件日誌中,也可能會收到下列訊息:

意外地停止 Aspnet_wp.exe (或 W3wp.exe,用於執行 Microsoft 網際網路資訊服務 [IIS] 6.0 的應用程式)。

在此處理程序期間您可能也注意到 Web 伺服器的記憶體使用率的增加。

發生的原因

Web 伺服器電腦的硬體設定會決定最大檔案大小,您可以成功地下載。當 ASP.NET 背景工作處理序 (Aspnet_wp.exe 或在網際網路資訊服務 6.0 [IIS] 執行的應用程式的 W3wp.exe) 執行檔案下載要求 [檔案下載] 對話方塊隨即出現。ASP.NET 背景工作處理序就會開始將資料傳送至 [Microsoft 網際網路資訊服務處理 (Inetinfo.exe 或 Dllhost.exe)。它不會等待您按 [確定]

根據電腦的設定,IIS 處理序可能會處理該資料,或是資料可能會緩衝記憶體中]。當檔案大時資料將緩衝記憶體中這些兩個處理序之間通訊期間。這可能會造成記憶體的使用率,在伺服器上資訊的增加。錯誤發生的原因,是因為記憶體的限制,在 Web 伺服器上。

其他可行方案

如果要解決這個問題,使用其中一種下列方法:
  • 取得小部份的資料,並再將資料移至輸出資料流,以供下載。下列程式碼會示範如何執行這項操作。

    重要 當您將設定編譯元素的 [偵錯] 屬性的值為 false 在 ASP.NET 應用程式的 Web.config 檔中時,Server.ScriptTimeout 屬性必須設適合檔案下載大小的值。 預設情況下,Server.ScriptTimeout 值設定為 90 秒。 不過,當 偵錯] 屬性設為 true 時,Server.ScriptTimeout 值將被設定非常大 30,000,000 秒。 身為開發人員必須知道這可能對您的 ASP.NET Web 應用程式行為的影響。

    而且,遵循您的程式碼中必須知道的參數值與 FileStream 建構函式一起使用。列舉值,指定了在提供的功能上進行重大的影響。如需詳細資訊請參閱 [REFERENCES] 區段中的 [FileStream] 連結。
    Visual Basic.NET 程式碼
          Dim iStream As System.IO.Stream
    
          ' Buffer to read 10K bytes in chunk:
          Dim buffer(10000) As Byte
    
          ' Length of the file:
          Dim length As Integer
    
          ' Total bytes to read:
          Dim dataToRead As Long
    
          ' Identify the file to download including its path.
          Dim filepath As String = "DownloadFileName"
    
          ' Identify the file name.
          Dim filename As String = System.IO.Path.GetFileName(filepath)
    
          Try
             ' Open the file.
             iStream = New System.IO.FileStream(filepath, System.IO.FileMode.Open, _
                                                    IO.FileAccess.Read, IO.FileShare.Read)
    
             ' Total bytes to read:
             dataToRead = iStream.Length
             
             Response.ContentType = "application/octet-stream"
             Response.AddHeader("Content-Disposition", "attachment; filename=" & filename)
    
             ' Read the bytes.
                While dataToRead > 0
                    ' Verify that the client is connected.
                    If Response.IsClientConnected Then
                        ' Read the data in buffer
                        length = iStream.Read(buffer, 0, 10000)
    
                        ' Write the data to the current output stream.
                        Response.OutputStream.Write(buffer, 0, length)
    
                        ' Flush the data to the HTML output.
                        Response.Flush()
    
                        ReDim buffer(10000) ' Clear the buffer
                        dataToRead = dataToRead - length
                    Else
                        'prevent infinite loop if user disconnects
                        dataToRead = -1
                    End If
                End While
    
          Catch ex As Exception
             ' Trap the error, if any.
             Response.Write("Error : " & ex.Message)
          Finally
             If IsNothing(iStream) = False Then
                ' Close the file.
                iStream.Close()
             End If
             Response.Close()
          End Try
    
    Visual C#.NET 代碼
    	System.IO.Stream iStream = null;
    
    	// Buffer to read 10K bytes in chunk:
    	byte[] buffer = new Byte[10000];
    
    	// Length of the file:
    	int length;
    
    	// Total bytes to read:
    	long dataToRead;
    
    	// Identify the file to download including its path.
    	string filepath  = "DownloadFileName";
    
    	// Identify the file name.
    	string  filename  = System.IO.Path.GetFileName(filepath);
    
    	try
    	{
    		// Open the file.
    		iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, 
    					System.IO.FileAccess.Read,System.IO.FileShare.Read);
    
    
    		// Total bytes to read:
    		dataToRead = iStream.Length;
    
    		Response.ContentType = "application/octet-stream";
    		Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    
    		// Read the bytes.
      		while (dataToRead > 0)
    		{
    			// Verify that the client is connected.
    			if (Response.IsClientConnected) 
    			{
    				// Read the data in buffer.
    				length = iStream.Read(buffer, 0, 10000);
    
    				// Write the data to the current output stream.
    				Response.OutputStream.Write(buffer, 0, length);
    
    				// Flush the data to the HTML output.
    				Response.Flush();
    
    				buffer= new Byte[10000];
    				dataToRead = dataToRead - length;
    			}
    			else
    			{
    				//prevent infinite loop if user disconnects
    				dataToRead = -1;
    			}
    		}
    	}
    	catch (Exception ex) 
    	{
    		// Trap the error, if any.
    		Response.Write("Error : " + ex.Message);
    	}
    	finally
    	{
    		if (iStream != null) 
    		{
    			//Close the file.
    			iStream.Close();
    		}
    		Response.Close();
    	}
    	
    取代 DownloadFileName 大於 100 百萬位元組 (MB) 的檔案名稱。

    -或者-
  • 提供使用者下載檔案的連結。

    -或者-
  • 使用 Microsoft ASP 3.0 的下載項目,或使用軟體與 ASP Artisans FileUp。

    -或者-
  • 建立 ISAPI 擴充程式下載檔案。

    -或者-
  • 使用 FTP 下載檔案。

狀況說明

這種行為是經過設計規劃的。

其他相關資訊

重製行為的步驟

  1. 在 Microsoft Visual Basic.NET 中或在 Microsoft Visual C#.NET,建立新的 Web 應用程式專案。根據預設值,WebForm1.aspx,即建立。
  2. 從 [工具] 方塊中,將 按鈕物件 拖曳至 WebForm1.aspx。
  3. 連按兩下 按鈕物件 以開啟 [程式碼檢視中的 [按一下] 事件。
  4. 下列程式碼貼 Button1 Click 事件中。

    Visual Basic.NET 程式碼
    	' Identify the file to download including its path.
    	Dim filepath As String = DownloadFileName
    
    	' Identify the file name.
    	Dim filename As String = System.IO.Path.GetFileName(filepath)
    
    	Response.Clear()
    	
    	' Specify the Type of the downloadable file.
    	Response.ContentType = "application/octet-stream"
    
    	' Set the Default file name in the FileDownload dialog box.
    	Response.AddHeader("Content-Disposition", "attachment; filename=""" & filename & """")
    
    	Response.Flush()
    
    	' Download the file.
    	Response.WriteFile(filepath)

    Visual C#.NET 代碼
    	// Identify the file to download including its path.
    	string filepath = DownloadFileName;
    
    	// Identify the file name.
    	string filename = System.IO.Path.GetFileName(filepath);
    
    	Response.Clear();
    
    	// Specify the Type of the downloadable file.
    	Response.ContentType = "application/octet-stream";
    
    	// Set the Default file name in the FileDownload dialog box.
    	Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    
    	Response.Flush();
    
    	// Download the file.
    	Response.WriteFile(filepath);
  5. DownloadFileName 取代為大於 100 MB 的檔案名稱。
  6. 在 [偵錯] 功能表上按一下 [開始]。
  7. 按一下 [Button1]。

?考

如需詳細資訊按一下 [下面的文件編號,檢視 「 Microsoft 知識庫 」 中 「 文件]:
307603 如何使用 ASP.NET 和 Visual Basic.NET 瀏覽器中寫入二進位檔案
306654 如何使用 ASP.NET 和 Visual C#.NET 瀏覽器中寫入二進位檔案
如需詳細資訊請造訪下列 Microsoft 開發 o 人 h 員 ? 工 u 具 ? 網路 (MSDN) 網站]:
http://msdn2.microsoft.com/en-us/library/system.io.filestream(vs.71).aspx

屬性

文章編號: 812406 - 上次校閱: 2007年11月21日 - 版次: 4.3
這篇文章中的資訊適用於:
  • Microsoft Web Services Enhancements for Microsoft .NET 1.1
  • Microsoft ASP.NET 1.1
  • Microsoft ASP.NET 1.0
關鍵字:?
kbmt kbwebserver kbwebforms kbweb kbdownload kbprb KB812406 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:812406
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com