27

I noticed that it will keep returning the same read characters over and over, but I was wondering if there was a more elegant way.

abw333
  • 5,571
  • 12
  • 41
  • 48

5 Answers5

55
while(!streamReader.EndOfStream)
{
    string line = streamReader.ReadLine();
    Console.WriteLine(line);
}
Console.WriteLine("End of File");
harryovers
  • 3,087
  • 2
  • 34
  • 56
  • For a `NetworkStream` (from `TcpClient.GetStream`) underneath, accessing `EndOfStream` gives me a `IOException` if the remote end terminates first : `Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host` – KFL Mar 29 '18 at 23:02
  • This is a bad example. ReadLine will block until a new line character is reached. Its a bad assumption that your data will have a new line character. You stream buffer will fill up, and your application will hang waiting for that buffer to be read. – Dan Sep 27 '18 at 22:30
  • 2
    @Dan what would you propose as a solution instead of using ReadLine? – harryovers Sep 28 '18 at 13:41
5

Check StreamReader.EndOfStream. Stop your read loop when this is true.

Make sure your code correctly handles the returned value for "byte count just read" on ReadBlock calls as well. Sounds like you are seeing zero bytes read, and just assuming the unchanged buffer contents you see is another read of the same data.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
2

Unfortunately I can't comment on answers yet, but to the answer by "The Moof"...

Your use of cur here is misplaced, as the index parameter is for the index in buffer where writing is to begin. So for your examples it should be replaced by 0 in the call to stream.ReadBlock.

PL-Li2
  • 21
  • 1
2

When the returned read length is less than your requested read length, you're at the end. You also should be keeping track of the read length in case your stream size isn't a perfect match for your buffer size, so you need to account for the shorter length of the data in your buffer.

do{
     len = stream.ReadBlock(buffer, 0, buffer.Length);
     /* ... */
  }while(len == buffer.Length);

You could also check the EndOfStream flag of the stream in your loop condition as well. I prefer this method since you won't do a read of '0' length (rare condition, but it can happen).

do{
      len = stream.ReadBlock(buffer, 0, buffer.Length);
      /* ... */
  }while(!stream.EndOfStream);
The Moof
  • 794
  • 4
  • 10
1

From MSDN for ReadBlock():

Return Value Type: System.Int32 The position of the underlying stream is advanced by the number of characters that were read into buffer. The number of characters that have been read. The number will be less than or equal to count, depending on whether all input characters have been read.

So I would assume it's EOF when it returns 0,

Bala R
  • 107,317
  • 23
  • 199
  • 210