BinaryWrite to the Response object does not work when the binary file exceeds 4 MB

If you are using the ADODB.Stream object to read in a binary file and then writing that stream to the Response object, you will encounter problems when the binary file exceeds 4 MB. This is due to a buffering restriction implemented in IIS 6.0. Additonally, setting Response.Buffer = False will not solve the problem alone.

The buffering limit in IIS limits the amount of memory that can be used for each page request. So if you attempt to read in the entire stream into memory with the statement "objStream.Read(-1)" IIS will not permit it because of this buffering restriction.

There is a way to get this to work and get around the error. You still need to set Response.Buffer = False. You will also need to place your BinaryWrite statement into a loop that reads the Stream in chunks and subsequently writes this data directly to the output stream (via Response.BinaryWrite). This reduces the memory pressure used by the page request to the size of the chunk. For performance, you should also use the Response.IsClientConnected property to determine whether your visitor is still downloading or has cancelled the download. This allows your code to finish processing early and save network bandwidth if the visitor does not complete the download.

The example shown will read in a .pdf file and write this stream to the Response object. Reading in a stream using 256K chunks is well within the buffer restrictions of IIS. The code is for classic ASP using VBScript, but the concepts translate easily to ASP.NET

Dim chunkSize, stream

chunkSize = 262144 ' Read the stream in 256K chunks
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = 1
stream.LoadFromFile "m:\web\users\Account ID\Path to the file"
Response.Expires = 0

'Turn off buffering
Response.Buffer = False
Response.ContentType = "application/pdf"

' enclose the binarywrite statement in a loop that
' will read your stream in a specified chunk size

While Response.IsClientConnected And (stream.Position < stream.Size)

Set stream = Nothing

Article ID: 330, Created On: 5/13/2004, Modified: 5/14/2004

Feedback (0)