I'm just writing an simple method witch reading data from a general stream - which means it could be possibly a FileStream or a NetworkStream without knowing the length of it. I repeatly read the stream into a byte[] and push the data to another stream or whatever. My question is, how can I notice the stream is finished? I tried to return when the Read method returns 0 - is it the right way to do so? It seems that it's ok for reading files but meet problems for reading data from network, sometimes.
For network streams, if Stream.ReadByte() returns anything less than 0 you know that the stream was read to the end.
Yes, calling Read
repeatedly and finishing when it returns 0 is exactly the right way to do it.
Network streams are fine with this as well - they will block until any data is received or the stream is disconnected. Look at the documentation for Stream.Read
:
The return value is zero only if the position is currently at the end of the stream. The implementation will block until at least one byte of data can be read, in the event that no data is available. Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file).
As Jon says, you know it's the end of file because it will return 0 bytes. However, you must also take into account various exceptions that can be thrown. Because a network is inherantly unreliable, some exceptions will always be possible.
For example, if the stream is disconnected (as opposed to the other side simply closing the socket) then you might receive an IOException exception. Always wrap IO calls in exception handlers, unless you are absolutely certain they can't throw an exception.