Proper way to read a File to a Byte[] and vice versa

  • Thread starter Thread starter james
  • Start date Start date
J

james

I have a FileStream retrieved from FileOpenDialog. I have a Byte[] which I
intend to store for later use. What is the most efficient way of getting
the File into my Byte[] and tehn back out to a new FileStream ? I have been
looking at all the Readers and Writers and due to information overload
cannot decide on the proper method.

Thanks,

JIM
 
James,

It's quite simple. Assuming that you have a FileStream and it is
positioned at the first byte in the file, you can do this:

// Assume pobjStream is the filestream.
byte pbytBytes[] = new byte[pobjStream.Length];

// Read the bytes.
pobjStream.Read(pbytBytes, 0, pobjStream.Length);

That's really all there is to it. However, you have to be careful, for
large files, this can take up a huge chunk of memory. If it is possible to
process your file in smaller chunks, I would recommend doing that.

Hope this helps.
 
Nick,

Thanks a lot, that should work. I guess I got caught up in all the Stream
classes and the Readers and Writers... that I missed the simple way to do
it. Also I was looking for a method like GetBytes or like GetBuffer that is
on MemoryStream to do it all in one go without having to specify ranges.

JIM


Nicholas Paldino said:
James,

It's quite simple. Assuming that you have a FileStream and it is
positioned at the first byte in the file, you can do this:

// Assume pobjStream is the filestream.
byte pbytBytes[] = new byte[pobjStream.Length];

// Read the bytes.
pobjStream.Read(pbytBytes, 0, pobjStream.Length);

That's really all there is to it. However, you have to be careful, for
large files, this can take up a huge chunk of memory. If it is possible to
process your file in smaller chunks, I would recommend doing that.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

james said:
I have a FileStream retrieved from FileOpenDialog. I have a Byte[]
which
I
intend to store for later use. What is the most efficient way of getting
the File into my Byte[] and tehn back out to a new FileStream ? I have been
looking at all the Readers and Writers and due to information overload
cannot decide on the proper method.

Thanks,

JIM
 
Nicholas Paldino said:
It's quite simple. Assuming that you have a FileStream and it is
positioned at the first byte in the file, you can do this:

// Assume pobjStream is the filestream.
byte pbytBytes[] = new byte[pobjStream.Length];

// Read the bytes.
pobjStream.Read(pbytBytes, 0, pobjStream.Length);

That's really all there is to it. However, you have to be careful, for
large files, this can take up a huge chunk of memory. If it is possible to
process your file in smaller chunks, I would recommend doing that.

That's not quite all there is to it. Unless I've missed something,
FileStream.Read (like other streams) isn't guaranteed to return you all
the data you asked for in one lump. (Even if FileStream does guarantee
it, I wouldn't suggest relying on it - it's far too easy to get into
bad habits that way, and not notice when suddenly you're reading from a
NetworkStream instead of a FileStream, etc.)

See http://www.pobox.com/~skeet/csharp/readbinary.html
 
james said:
Thanks a lot, that should work. I guess I got caught up in all the Stream
classes and the Readers and Writers...

Readers and Writers are for when you want to convert binary to text or
vice versa. Streams are for binary data.
 
Jon,

Thanks for the warning, I am only expecting to be reading file streams, so I
could test for the Type and only procede if it is a file stream, but just to
clarify, in your example code at
http://www.pobox.com/~skeet/csharp/readbinary.html , is the first non safe
way (as Nick suggested) only non-safe when you are dealing with a non file
stream or could I run into troubl with File streams too ??

Thanks,

JIM



Jon Skeet said:
Nicholas Paldino said:
It's quite simple. Assuming that you have a FileStream and it is
positioned at the first byte in the file, you can do this:

// Assume pobjStream is the filestream.
byte pbytBytes[] = new byte[pobjStream.Length];

// Read the bytes.
pobjStream.Read(pbytBytes, 0, pobjStream.Length);

That's really all there is to it. However, you have to be careful, for
large files, this can take up a huge chunk of memory. If it is possible to
process your file in smaller chunks, I would recommend doing that.

That's not quite all there is to it. Unless I've missed something,
FileStream.Read (like other streams) isn't guaranteed to return you all
the data you asked for in one lump. (Even if FileStream does guarantee
it, I wouldn't suggest relying on it - it's far too easy to get into
bad habits that way, and not notice when suddenly you're reading from a
NetworkStream instead of a FileStream, etc.)

See http://www.pobox.com/~skeet/csharp/readbinary.html
 
james said:
Thanks for the warning, I am only expecting to be reading file streams, so I
could test for the Type and only procede if it is a file stream, but just to
clarify, in your example code at
http://www.pobox.com/~skeet/csharp/readbinary.html , is the first non safe
way (as Nick suggested) only non-safe when you are dealing with a non file
stream or could I run into troubl with File streams too ??

I don't know for sure. The docs for FileStream.Read *suggest* that it
may not be safe, but my guess is that it will be for local files.

Why take the risk though? It's so easy to load it all reliably in a
single method call, why not use that?

If you're worried about the efficiency aspect, you could adapt the code
so that it didn't use a MemoryStream, but used a buffer it could return
directly, and which you'd expand/copy in the same way as MemoryStream
does. By creating it with a good size guess (eg using Stream.Length) to
start with, you may well be able to make things faster and less memory
hungry. Don't forget to trim the array if you end up with a buffer
which is larger than the actual data though...
 
Jon,

I am using your ReadFully (NetworkStream stream) (as you can see i changed the parameter from Stream to NetworkStream).The problem i am having is when i am reading from the stream using the ReadFully method it seems like i am nor breaking out of the while loop.This occurs when i am sending the data into the stream from a telnet command window?(i am writing an smtp server and i am trying to test out with telneting to the ip and port with which my server is listening to)
Any suggestions would be appreciated.

Vinny


Jon Skeet said:
Nicholas Paldino said:
It's quite simple. Assuming that you have a FileStream and it is
positioned at the first byte in the file, you can do this:

// Assume pobjStream is the filestream.
byte pbytBytes[] = new byte[pobjStream.Length];

// Read the bytes.
pobjStream.Read(pbytBytes, 0, pobjStream.Length);

That's really all there is to it. However, you have to be careful, for
large files, this can take up a huge chunk of memory. If it is possible to
process your file in smaller chunks, I would recommend doing that.

That's not quite all there is to it. Unless I've missed something,
FileStream.Read (like other streams) isn't guaranteed to return you all
the data you asked for in one lump. (Even if FileStream does guarantee
it, I wouldn't suggest relying on it - it's far too easy to get into
bad habits that way, and not notice when suddenly you're reading from a
NetworkStream instead of a FileStream, etc.)

See http://www.pobox.com/~skeet/csharp/readbinary.html
 
<"=?Utf-8?B?VmlubnkgVmlubg==?=" <Vinny
I am using your ReadFully (NetworkStream stream) (as you can see i
changed the parameter from Stream to NetworkStream).The problem i am
having is when i am reading from the stream using the ReadFully
method it seems like i am nor breaking out of the while loop.This
occurs when i am sending the data into the stream from a telnet
command window?(i am writing an smtp server and i am trying to test
out with telneting to the ip and port with which my server is
listening to)
Any suggestions would be appreciated.

Sure - the problem is that the server isn't terminating the connection,
so the stream is never finished. With a stream, there's no concept of
"finished this bit" which is what I think you want. You need to read
from the stream until the protocol itself tells you that this bit has
finished - for instance, with a dot on a line on its own, in many
protocols.
 
Back
Top