Я ищу, чтобы прочитать следующий символ UTF8 из Stream или BinaryReader. Вещи, которые не работают:Чтение одного символа UTF8 из потока в C#
BinaryReader :: ReadChar - это набросит символ 3 или 4 байта. Поскольку он возвращает структуру двух байтов, у него нет выбора.
BinaryReader :: ReadChars - это будет выдаваться, если вы попросите его прочитать 1 символ, и он встретит символ 3 или 4 байта. Будет читать несколько символов, если вы попросите его прочитать более 1 символа.
StreamReader :: Read - это должно знать, сколько байтов читать, но количество байтов в символе UTF8 является переменной.
код я, что, кажется, работает:
private char[] ReadUTF8Char(Stream s)
{
byte[] bytes = new byte[4];
var enc = new UTF8Encoding(false, true);
if (1 != s.Read(bytes, 0, 1))
return null;
if (bytes[0] <= 0x7F) //Single byte character
{
return enc.GetChars(bytes, 0, 1);
}
else
{
var remainingBytes =
((bytes[0] & 240) == 240) ? 3 : (
((bytes[0] & 224) == 224) ? 2 : (
((bytes[0] & 192) == 192) ? 1 : -1
));
if (remainingBytes == -1)
return null;
s.Read(bytes, 1, remainingBytes);
return enc.GetChars(bytes, 0, remainingBytes + 1);
}
}
Очевидно, это немного беспорядок, и несколько специфична в UTF8. Есть ли более элегантное, менее обычное, более легкое для чтения решение этой проблемы?
Возможный дубликат http://stackoverflow.com/questions/11671826/how-do-you-read-utf-8-characters-from- an-infin-byte-stream-c-sharp –
Вопрос может быть дубликатом, но этот ответ не работает. В частности, он не обрабатывает суррогатные пары. Я попытался изменить его, чтобы использовать 2-элементный буфер символов, но это только что вызвало другую проблему. Кроме суррогатных пар, все равно работает. – DDurschlag
Прохладный, я не был на 100% уверен, что если бы это было то же самое, но я подумал, что в нем может быть полезная информация. –