I have a StreamReader
object that I initialized with a stream, now I want to save this stream to disk (the stream may be a .gif
or .jpg
or .pdf
).
Existing Code:
StreamReader sr = new StreamReader(myOtherObject.InputStream);
- I need to save this to disk (I have the filename).
- In the future I may want to store this to SQL Server.
I have the encoding type also, which I will need if I store it to SQL Server, correct?
You must not use
StreamReader
for binary files (like gifs or jpgs).StreamReader
is for text data. You will almost certainly lose data if you use it for arbitrary binary data. (If you use Encoding.GetEncoding(28591) you will probably be okay, but what's the point?)Why do you need to use a
StreamReader
at all? Why not just keep the binary data as binary data and write it back to disk (or SQL) as binary data?EDIT: As this seems to be something people want to see... if you do just want to copy one stream to another (e.g. to a file) use something like this:
To use it to dump a stream to a file, for example:
Note that
Stream.CopyTo
was introduced in .NET 4, serving basically the same purpose.I don't get all of the answers using
CopyTo
, where maybe the systems using the app might not have been upgraded to .NET 4.0+. I know some would like to force people to upgrade, but compatibility is also nice, too.Another thing, I don't get using a stream to copy from another stream in the first place. Why not just do:
Once you have the bytes, you can easily write them to a file:
This code works as I've tested it with a
.jpg
file, though I admit I have only used it with small files (less than 1 MB). One stream, no copying between streams, no encoding needed, just write the bytes! No need to over-complicate things withStreamReader
if you already have a stream you can convert tobytes
directly with.ToArray()
!Only potential downsides I can see in doing it this way is if there's a large file you have, having it as a stream and using
.CopyTo()
or equivalent allowsFileStream
to stream it instead of using a byte array and reading the bytes one by one. It might be slower doing it this way, as a result. But it shouldn't choke since the.Write()
method of theFileStream
handles writing the bytes, and it's only doing it one byte at a time, so it won't clog memory, except that you will have to have enough memory to hold the stream as abyte[]
object. In my situation where I used this, getting anOracleBlob
, I had to go to abyte[]
, it was small enough, and besides, there was no streaming available to me, anyway, so I just sent my bytes to my function, above.Another option, using a stream, would be to use it with Jon Skeet's
CopyStream
function that was in another post - this just usesFileStream
to take the input stream and create the file from it directly. It does not useFile.Create
, like he did (which initially seemed to be problematic for me, but later found it was likely just a VS bug...).Another option is to get the stream to a
byte[]
and useFile.WriteAllBytes
. This should do:Wrapping it in an extension method gives it better naming: