I have a Stream which is
Stream stream = httpWebResponse.GetResponseStream();
I need to convert this System.IO.Stream into System.IO.MemoryStream.
How can I do that with C# 2003
The data that a server returns is an image.
I would do
byte [] data = webClient.DownloadData(uri);
but for certain reasons I have to use HttpWebRequest/Response.
Thank you.

Converting streams
ef
My task was: the method has to download an image from a remote server and return it as a byte array. So, I had to find a way to convert a stream into a byte [].
This particular format - jpeg - is just as good as any, but the client application prefers jpeg, because with other formats we had some weird problems in the past and had to use a wrapper from LEAD Technologies, which solved the problems, but added unnecessary overhead to performance. Besides, jpegs themselves are rather small, and that's another reason to use them..
Nick Gabello
Jon
SEH
Big thanks to everybody.
Here's how I did this:
----------------------
httpWebResponse = (HttpWebResponse)req.GetResponse();
stream = httpWebResponse.GetResponseStream();
image = (Bitmap)Image.FromStream(stream);
msTemp = new MemoryStream();
image.Save(msTemp, System.Drawing.Imaging.ImageFormat.Jpeg);
byte [] data = msTemp.ToArray();
.....
finally
{
if (stream != null) stream.Close();
if (httpWebResponse != null) httpWebResponse.Close();
if (image != null) image.Dispose();
if (msTemp != null) msTemp.Close();
}
return data;
--------------
So, in this particular situation (download image --> return it as a byte array) the code above works just fine (already on production server :-) ).
--------------
That was a brilliant idea from GregBeech from gotdotnet forums. Thanks a lot!
lcdmendes
I totally hear you. We were using the LEAD components for vb6...
I switched to my custom image optimization and resizing code in .net...
you can see the outputs on:
http://www.fraseryachts.net/FraserConnWs/GetYachtPicture.aspx p=11544_MC
you can get a non-distorted, non-pixelerated thumbnail like :
http://www.fraseryachts.net/FraserConnWs/GetYachtPicture.aspx p=11544_MC&w=150
or:
http://www.fraseryachts.net/FraserConnWs/GetYachtPicture.aspx p=11544_MC&h=150
or if you insist on distorting it you can say
http://www.fraseryachts.net/FraserConnWs/GetYachtPicture.aspx p=11544_MC&w=150&h=150
You will not be able to right click and see the image size in bytes, because of hte issue I have mentioned above... :) and if you save it IExplore will save it as a BITMAP, and you will end up with a larger size...
I have written a Bitmap helper, which wraps the most common Bitmap transformation procedures. I can share if you like...
DeepakGH
http://www.pobox.com/~skeet/csharp/readbinary.html
Alternatively, if you want to end up with a Stream, you can read chunks from the returned stream and write them into a MemoryStream, then set the MemoryStream's Position to 0 when you've finished reading the original stream.
Jon
fudicator
Note that your finally block is slightly broken - if any of the calls to Close() etc throw an exception, the later ones won't get called. If you use "using" statements instead, this is avoided.
Jon
casgo
binaryReader.ReadBytes((int)stream.Length);
you get an exception "Seek not supported"
I have a similar issue... trying to read a HTTPResponse that has no Content-length header.
dont know what would be a good solution for that, any ideas
Big-O
And how do you suggest doing this using a HTTPWebRequest
The WebClient does have a suitable method for reading all the bytes as fafnir suggested above, but his question was how do you accomplish this using HTTPWebRequest
If you have the content-length header, then you can set the size of your bytearray to that size, and read it from the response stream... no problems.
My question is what is the way to do it when there is no content-length header ...
Here is an example URL that has no content-length header:
http://www.fraseryachts.net/FraserConnWs/GetYachtPicture.aspx p=11544_MC
The reason why this URL does not have a content-length is, there exists NO method or property that will give you the actual filesize (or the length of the bytes) of a Bitmap (or Image ), unless you persist it to the disk, or to a memory stream... Which I do not want to do when I am already saving it to the response output stream, performance being the major reason...
I read the original bitmap, create a resized bitmap, paint the optimized image, paint my border and watermark, and save it to the response stream... I could not find a way to READ the content-length of the response stream within this process WITHOUT an additional SAVE to another stream.
Any suggestions on both ends
Here is the code to save the image:
Response.Clear();
true;Response.Buffer =
// set the mime type
Response.ContentType = "image/jpeg";
Response.AddHeader("content-type", "image/jpeg");
Response.AddHeader("content-disposition", "inline; filename=" + p + ".jpg");
// send the image to the viewer
outputbitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
original.Dispose();
resized.Dispose();
outputbitmap.Dispose();
//The code below throws a System.NotSupportedException: Specified method is not supported.
//So, you cannot read the length of the outputstream...
//You also cannot read the byte size of the output bitmap...
//You are already trying to add a header AFTER you write the body of the response,
//which is weird to begin with
//Let the consumer deal with it at this moment:)
//Response.AddHeader("content-length", Response.OutputStream.Length.ToString());
Response.Flush();
Thanks
ssloka
If you are copying it to a (SQL server) database, you need the byte[], the stream would not work. And the response stream does not give you the length of the bytes it has.
That is one valid reason why you need to take an additional step to get the bytes, weather it is saving it to a memorystream, or converting it to an image and reading the bytes from the image...
ImpureEvil
True... I would also go with the MemoryStream option...will perform faster.
As for resizing an array, I think is is a little clumsy with the ResponseStream
R_oo_T
The solution is to process the stream into a string or a byte array directly without using the ReadBytes overload that requires the number of bytes to process.
Hope that helps.
Bruce Johnson [C# MVP]
http://www.objectsharp.com/blogs/bruce
Simsabim
You can't convert it from one to the other .. you would read data from that stream into a memory stream.
Although I am curious why you need to read it into a memory stream as opposed to using the response stream directly
I can write code such as ..
public void DoSomething(Stream s) {
//read data off of stream
}
That will work on either stream.
Cheers,
Greg
dev.McClannahan411
You also might try the following, if you are ultimately trying to put your data into a byte array
System.Net.
HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest) System.Net.HttpWebRequest.Create(uri);System.Net.
HttpWebResponse httpWebResponse = (System.Net.HttpWebResponse) httpWebRequest.GetResponse();System.IO.
Stream stream = httpWebResponse.GetResponseStream();System.IO.
BinaryReader binaryReader = new System.IO.BinaryReader(stream); byte[] imageData = binaryReader.ReadBytes((int)stream.Length);Neeti
My question would be if you are actually converting images to JPEG format for a reason (or if you just need the bytes of the original image).
if there is no need for a conversion
httpWebResponse = (HttpWebResponse)req.GetResponse();
stream = httpWebResponse.GetResponseStream();
stream already contains the bytes of the original image.