HttpPostedFile.InputStream.ReadTimeout

  • Thread starter Thread starter macap.usenet
  • Start date Start date
M

macap.usenet

Hello,

I´ve a strange problem with my HttpPostedFile object.

I coded a File Upload where the user can upload a zip file. My code
looks like this:

HttpFileCollection files = Page.Request.Files;
HttpPostedFile file = files[0];

When I set a breakpoint at the second line and run the debugger,
the debugger tolds me in the properties of my object "file":

ReadTimeout = "file.InputStream.ReadTimeout" throws an Exception of
Typ "System.InvalidOperationException"

WriteTimeout = "file.InputStream.WriteTimeout"throws an Exception of
Typ "System.InvalidOperationException"


Does anybody have an idea what happens?


Regards,

Martin
 
This is normal and just means that the stream doesn't support
read/write timeouts.

Most streams don't; the base-class (System.IO.Stream) has "CanTimeout"
return false, and "ReadTimeout" / "WriteTimeout" throw an Exception.
The System.Web.HttpPostedFile functionality uses a
System.Web.HttpInputStream which doesn't alter this behavior.

Is this causing a problem, or just out of interest?

Marc
 
Hi Marc,

thank you!

This is normal and just means that the stream doesn't support
read/write timeouts.

Well... in my opinion, it´s not a good coding style, if an Exception
is "normal".
Is this causing a problem, or just out of interest?

I am having trouble with reading the stream into a byte-array and I am
not sure,
if the Exception is the cause of the problem.

My code looks like this:

BufferedStream bs = new BufferedStream(file.InputStream);
int length = System.Convert.ToInt32(bs.Length);
byte[] zipFile = new byte[length];

// wandle Zip-File in byte[] um
int offset = 0;
int remaining = length;
while (remaining > 0)
{
int read = bs.Read(zipFile, offset, remaining);
if (read <= 0)
throw new EndOfStreamException(String.Format("End of
stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}


Before entering the while-loop the values of my variables are int
remaining = 1189816 = length
In the first iteration of the while loop, the Read method reads 7109
bytes (int read = 7109).
After this, the variables have values int remaining = 1182707 and int
offset = 7109. In the second while-loop, the Read method
(bs.Read(zipFile, 7109, 1182707) does not read any byte(!!!), which
means int read = 0.

Do you have an idea why that happens?


Regards,
Martin
 
I am having trouble with reading the stream into a byte-array and I am
not sure,
if the Exception is the cause of the problem.

My code looks like this:

BufferedStream bs = new BufferedStream(file.InputStream);
int length = System.Convert.ToInt32(bs.Length);
byte[] zipFile = new byte[length];

// wandle Zip-File in byte[] um
int offset = 0;
int remaining = length;
while (remaining > 0)
{
int read = bs.Read(zipFile, offset, remaining);
if (read <= 0)
throw new EndOfStreamException(String.Format("End of
stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;

}

When I store the HttpPostedFile temporary and read it with a
FileStream after that,
everything works fine:

file.SaveAs("C:\\tmp\\test.zip"); // file is an object of
HttpPostedFile
FileStream fs = new FileStream(@"C:\\tmp\\testtesttest.zip",
FileMode.Open, FileAccess.Read);

// Create a byte array of file stream length
byte[] zipFile = new byte[fs.Length];

//Read block of bytes from stream into the byte array
fs.Read(zipFile, 0, System.Convert.ToInt32(fs.Length));

//Close the File Stream
fs.Close();


Does anybody know a better solution without storing the HttpPostedFile
into a tmp Folder?


Bye,
Martin


Btw: is there a way to get the path of the temp-folder as String?
I only found "System.Environment.SpecialFolder.InternetCache" which
does not give any path as string.
 
It might be better to use the ContentLength of the inbound file. The
following seems to work happily. Note that using a byte[] as a buffer
isn't very efficient; if you explain what you are *doing* with the
buffer afterwards, [we] might be able to suggest better approaches
that don't need all the data at once. For instance, you can write to a
database, or unpack a zip, directly from the inbound stream using
small buffers, not a buffer for the entire document (which might be a
good way to launch a DOS attack...)

Marc

if(Request.Files.Count > 0) {
HttpPostedFile file = Request.Files[0];
int remaining = file.ContentLength, offset = 0;
byte[] buffer = new byte[remaining];
while(remaining > 0) {
int bytesRead = file.InputStream.Read(buffer,
offset, remaining);
if(bytesRead<=0) throw new
InvalidOperationException("Oops");
remaining -= bytesRead;
offset += bytesRead;
}
}
 
Well... in my opinion, it´s not a good coding style, if an Exception
is "normal".

The exception isn't "normal", and doesn't relate to /any/ coding
style - it only happened because you are looking at the object via the
debugger. The correct way of using those properties is to check the
CanTimout first to see if they make sense; if it returns false you
shouldn't even be /looking/ at these values, so it is entirely
reasonble for it to throw an exception. The debugger doesn't care
about that, and simply asks for the value of every property.

For info, if you are working with zip, you might want to look at
SharpZipLib (ICSharpCode) - this should allow you to work with the
internals quite easily.

Marc
 
Back
Top