tags:

views:

637

answers:

6

I want to use ASP.NET and IIS to download dynamically generated files to the browser to be saved. I don't know the size of the file that will be generated.

In the current form, my code generates data and uses HttpResponse.Write() to send to the client. But the client sees no activity for about a minute, before finally showing the save file dialog.

By default, IIS buffers the output to be sent to the client. It is possible to turn this off, but that doesn't help in my case. The problem seems to be the way IIS chooses to format the packets.

If the file size is known ahead of time, then I could set the Content-length in the header. If I turned off output buffering, then presumably, IIS can start sending to the client right away.

But since I don't know the file size, IIS seems to be buffering the output until a certain limit is reached (packet size or time, I don't know), then sends a packet with Transfer-encoding set to chunked.

I could try chunking the data myself, but is there a way to get IIS to perform the chunking, but with a smaller packet size so that the dialog shows sooner?

A: 

Have you tried occasional calls to HttpResponse.Flush()?

Brad Wilson
Yes, they have no effect.
UncleO
A: 

Have you tried to set the BufferOutput property to false? One other thought (I don't know if that changes anything though) is to write the file to the OutputStream instead of calling HttpResponse.Write().

Fredrik Mörk
Yes, I set the BufferOutput to false, and used flush many times. All that does is slow it down even more.
UncleO
A: 

How do you not know the size of the file you're streaming to the browser? And do you mean Response.BinaryWrite ?

Nicholas H
The file content is generated from a database. And I'm using Write() at the moment.
UncleO
I would suggest adding a filesize field to your database and writing a utility to loop through and update them all. You're committing two big no-nos: 1) Storing files in the database 2) Streaming a file without saying how big it is first.
Nicholas H
Thanks, Nicholas. I must not be clear enough in the question. I'm generating output to be downloaded as a file at the browser. I'm not storing or streaming files, and I don't know what the length will be.
UncleO
A: 

Try somthing similar to:

byte[] response_bytes = ...
int offset = ...

using (Stream writeStream = HttpContext.Response.OutputStream)
{
    ...
    writeStream.Write(response_bytes, offset, response_bytes.Length);
}
eu-ge-ne
A: 

As of now, there are no acceptable answers, but I can share what I have learned.

I'm using IIS 6 and .NET framework 2.0.

It appears that it is IIS that is buffering the output, and not respecting my calls to Flush(). In fact, Flush() actually slows the download. It seems to just move the output from one process to another within IIS but less efficiently than if Flush() were not used.

Some interesting behaviour showed up in testing. If the output was small enough, IIS added the content-length to the header of the response, and then sent it.

If the output was too large, after about 60 seconds IIS added transfer-encoding: chunked to the header, then added the appropriate hex number and sent what it had. From there, the output was streamed as my Flush() calls occurred.

It didn't matter if I chunked the data myself. IIS still buffered the output until its buffer was full.

Maybe there is a better way to set the transfer-encoding in a newer framework, so that IIS 6 can deal with it better.

Another possibility is to try different settings in Metabase.xml. I ran out of time before investigating that further.

UncleO
A: 

Please, any solution about it ?? Thanks !!

I need download large file in IIS for xp and IIS for 2003.