Normalmente, para leer caracteres de una secuencia de bytes, utiliza un StreamReader. En este ejemplo, estoy leyendo registros delimitados por '\ r' desde una secuencia infinita.Cómo leer caracteres UTF-8 de una secuencia de bytes infinita - 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();
}
}
}
El problema es que el StreamReader tiene un pequeño buffer interno, por lo que si el código de espera de un 'fin del registro' delimitador ('\ r' en este caso) tiene que esperar hasta que el buffer interno del StreamReader está enrojecido (generalmente porque han llegado más bytes).
Esta implementación alternativa funciona para caracteres UTF-8 de un solo byte, pero fallará en caracteres multibyte.
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();
}
}
¿Cómo puedo modificar este código para que funcione con caracteres de varios bytes?
no debe modificarse el título decir de varios bytes o caracteres en lugar de UTF-16 UTF-8? Parece engañoso. –
@TimS. Los caracteres UTF-8 pueden ser más que un solo byte. – Iridium
@TimS. ¿Qué quieres decir? Un carácter multibyte UTF-8 no se convierte automágicamente en un carácter UTF-16. [Wiki] (http://en.wikipedia.org/wiki/UTF-8#Description). – CodeCaster