PRB: Response.WriteFile Cannot Download a Large File (812406)
The information in this article applies to:
- Microsoft Web Services (included with the .NET Framework 1.1)
- Microsoft ASP.NET (included with the .NET Framework 1.1)
- Microsoft ASP.NET (included with the .NET Framework) 1.0
SYMPTOMSWhen you try to use the Response.WriteFile method to download a large file, the download may not respond, and
then you may receive one of the following error messages: The page
cannot be displayed -or- Server Application
Unavailable
The Web application you are attempting to access on this
Web server is currently unavailable. Please hit the "Refresh" button in your
Web browser to retry your request.
Administrator Note: An error
message detailing the cause of this specific request failure can be found in
the system event log of the web server. Please review this log entry to
discover what caused this error to occur. You may also receive the
following message in the Application event log:Aspnet_wp.exe
(or W3wp.exe, for applications that run on Microsoft Internet Information Services [IIS] 6.0)
stopped unexpectedly.During this process, you may also notice an
increase in the memory utilization of the Web server. CAUSE The hardware configuration of the Web server computer
determines the maximum file size that you can successfully download. When the
ASP.NET worker process (Aspnet_wp.exe, or W3wp.exe for applications that run on Internet Information Services 6.0 [IIS])
runs the file download request, the file download dialog box appears. The
ASP.NET worker process starts to send the data to the Microsoft Internet
Information Services Process (Inetinfo.exe or Dllhost.exe). It does not
wait for you to click OK.
Depending on the
configuration of the computer, the IIS Process may process the data, or the
data may be buffered in memory. When the file is large, the data is buffered in
memory during communication between these two processes. This may cause an
increase in the memory utilization on the server. The error occurs because of
the memory constraints on the Web server.WORKAROUNDTo work around this issue, use any one of the following
methods:
- Obtain the data in small portions, and then move the data
to the output stream for download. The following code demonstrates how to do
this.
Important When you set the value of the debug attribute of the compilation element to false in the Web.config file of your ASP.NET application, you must set the Server.ScriptTimeout property to an appropriate value for the file download size. By default, the Server.ScriptTimeout value is set to 90 seconds. However, when the debug attribute is set to true, the Server.ScriptTimeout value will be set to a very large 30,000,000 seconds. As a developer, you must be aware of the impact that this may have on the behavior of your ASP.NET Web application.
Also, in the code that follows you must be aware of the
parameter values that are used with the FileStream constructor. The enumeration values
that are specifed make a significant impact on the functionality that is provided. For
more information, refer to the FileStream link in the
REFERENCES section. Visual
Basic .NET Code 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
End Try
Visual C# .NET Code 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();
}
}
Replace DownloadFileName with the name of a
file that is larger than 100 megabytes (MB).
-or- - Provide a link for the user to download the
file.
-or- - Use Microsoft ASP 3.0 for the downloads or use Software
Artisans FileUp with ASP.
-or- - Create an ISAPI extension to download the
file.
-or- - Use FTP to download the file.
STATUS This
behavior is by design.REFERENCES For additional information, click the following article
numbers to view the articles in the Microsoft Knowledge Base: 307603
HOW TO: Write Binary Files to the Browser Using ASP.NET and Visual Basic .NET
306654 HOW TO: Write Binary Files to the Browser Using ASP.NET and Visual C# .NET
For more information, visit the following Microsoft Developer Network (MSDN) Web site: Notice
The third-party products that are discussed in this article are manufactured by
companies that are independent of Microsoft. Microsoft makes no warranty,
implied or otherwise, regarding the performance or reliability of these
products.
Modification Type: | Major | Last Reviewed: | 11/25/2003 |
---|
Keywords: | kbWebServer kbWebForms kbweb kbDownload kbprb KB812406 kbAudDeveloper |
---|
|