Как лучше всего читать и UTF-8-декодировать байтовые буферы? - PullRequest
2 голосов
/ 25 августа 2011

У меня есть Stream, который производит UTF-8 кодированные строки. Строки представляют XML-документы, которые мне нужно проанализировать. Поток получается из TcpClient.

Предположим, я прочитал поток в буферы размером 64 (я знаю, немного меньше). Передача этих 64-байтовых буферов непосредственно на этап декодирования строки может быть неудачной, поскольку некоторые символы в кодировке UTF-8 могут быть разделены вдоль 64-байтовой границы. Буфер может заканчиваться первыми двумя байтами символа, а следующий буфер имеет последний байт для этого символа.

То, что я делаю сейчас, - это объединенные буферы, пока я не выполню чтение, которое не считывает полные 64 байта, что указывает на то, что я прочитал что-то до конца (в моем случае, документ XML). Однако время от времени прочитанные мной XML-документы заканчиваются точно на границе 64 байта. В таком случае я не знаю, могу ли я передать байтовый массив на шаг декодирования (и мне нужно дождаться следующего документа).

Я понимаю, что могу уменьшить шансы, увеличив размер буфера. Однако всегда остается небольшой шанс, что это произойдет. Я мог бы также увеличить размер буфера так, чтобы подойдет любой встречающийся XML-документ, но мне просто интересно, есть ли другое решение, каким-либо образом определяющее из потока байтов, где находятся символьные границы.

Ответы [ 2 ]

2 голосов
/ 25 августа 2011

Я считаю, что ваш подход теоретически ошибочен, даже если он должен всегда работать правильно на практике: нет гарантии, что успешное чтение меньше (размер буфера) указывает на то, что документ XML был получен полностью. Стек TCP полностью в пределах своих прав, чтобы возвращать документ по одному байту за раз. Увеличение размера буфера до нескольких КБ должно привести к возникновению этой проблемы.

Устранение вышеуказанного недостатка также решит вашу текущую проблему: добавьте какой-нибудь заголовок фиксированной длины (например, 8 байт), который содержит длину следующего документа перед каждым документом XML в вашем потоке TCP. Вы всегда будете знать, когда прочитали полный заголовок (потому что он имеет фиксированный размер), и с учетом заголовка вы узнаете, когда получите весь документ.

2 голосов
/ 25 августа 2011

Вы правы насчет проблем и подводных камней.

Решение уже существует: оберните StreamReader вокруг вашего потока и используйте Read() и ReadLine()

Если вы действительно хотите получить решение «сделай сам», вам придется взглянуть на энкодергосударственные свойства.Помимо моих возможностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...