Typically, StreamReader is used to read characters from a byte stream. In this example, I am reading records limited to '\ r' from an infinite stream.
using(var reader = new StreamReader(stream, Encoding.UTF8)) { var messageBuilder = new StringBuilder(); var nextChar = 'x'; while (reader.Peek() >= 0) { nextChar = (char)reader.Read() messageBuilder.Append(nextChar); if (nextChar == '\r') { ProcessBuffer(messageBuilder.ToString()); messageBuilder.Clear(); } } }
The problem is that the StreamReader has a small internal buffer, so if the code waiting for the 'end of record' separator ('\ r' in this case) must wait until the internal StreamReader buffer is flushed (usually because there are more bytes arrived).
This alternative implementation works for single bytes of UTF-8 characters, but will fail on multi-byte characters.
int byteAsInt = 0; var messageBuilder = new StringBuilder(); while ((byteAsInt = stream.ReadByte()) != -1) { var nextChar = Encoding.UTF8.GetChars(new[]{(byte) byteAsInt}); Console.Write(nextChar[0]); messageBuilder.Append(nextChar); if (nextChar[0] == '\r') { ProcessBuffer(messageBuilder.ToString()); messageBuilder.Clear(); } }
How can I change this code to work with multibyte characters?
source share