Zazwyczaj do odczytywania znaków ze strumienia bajtów używasz StreamReadera. W tym przykładzie czytam rekordy rozdzielane przez '\ r' z nieskończonego strumienia.Jak odczytujesz znaki UTF-8 z nieskończonego strumienia bajtów - C#
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();
}
}
}
Problemem jest to, że StreamReader ma mały bufor wewnętrzny, więc jeśli kod czekając na „koniec zapisu” ogranicznika („\ r” w tym przypadku), to musi czekać aż do wewnętrznego bufora StreamReader za jest spłukiwany (zwykle dlatego, że przybyło więcej bajtów).
Ta alternatywna implementacja działa dla jednobajtowych znaków UTF-8, ale nie powiedzie się dla znaków wielobajtowych.
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();
}
}
Jak mogę zmodyfikować ten kod, aby działał ze znakami wielobajtowymi?
nie powinien być modyfikowany tytuł powiedzieć wielo-bajtowy lub UTF-16 znaków zamiast UTF-8? Wydaje się wprowadzać w błąd. –
@TimS. Znaki UTF-8 mogą być więcej niż jednym bajtem. – Iridium
@TimS. co masz na myśli? Wielobajtowy znak UTF-8 nie automagicznie staje się znakiem UTF-16. [Wiki] (http://en.wikipedia.org/wiki/UTF-8#Description). – CodeCaster