обработка буфера в байтах [] на до-диез

#c# #unicode #bytearray

#c# #Юникод #массивы

Вопрос:

Я пишу класс, который используется для работы с byte[] буфером. Он содержит такие методы, как char Peek() и string ReadRestOfLine() .

Проблема в том, что я хотел бы добавить поддержку unicode, и я действительно не знаю, как мне следует изменить эти методы (сейчас они поддерживают только ASCII).

Как мне определить, что следующие байты в буфере представляют собой последовательность unicode (utf8 или utf16)? И как мне преобразовать их в char ?

Обновить

Да, класс немного похож на StreamReader , но с той разницей, что он будет избегать создания объектов (типа string , char[] ) и т.д., пока не будет найдена вся требуемая строка. Используется в высокопроизводительной среде сокетов.

Допустим, я хочу написать прокси, который будет проверять URI только в HTTP-запросе. Если бы я где использовать StreamReader , мне пришлось бы создавать временный массив символов каждый раз, когда был завершен новый прием, просто чтобы посмотреть, был ли получен новый символ строки.

Используя класс, который работает непосредственно с byte[] буфером, который socket.ReceiveAsync использует, мне просто нужно просмотреть буфер в моем анализаторе, чтобы узнать, можно ли выполнить следующий шаг. Временные объекты не создаются.

Для большинства протоколов в области заголовка используется ASCII, и UTF8 не будет проблемой (тело запроса может быть проанализировано с помощью StreamReader ). Мне просто интересно, как это можно решить, избегая создания ненужных объектов.

Комментарии:

1. Почему вы работаете непосредственно с такими строками вместо Encoding классов?

2. Почему вы не используете MemoryStream class в качестве базового типа? Почему бы вам не преобразовать это в string ?

Ответ №1:

Я не думаю, что вы хотите идти туда. Есть масса вещей, которые могут пойти не так. Прежде всего: какую кодировку вы используете? Тогда содержит ли буфер всю закодированную строку? Или это начинается с некоторой случайной позиции, возможно, внутри такой последовательности?

Ваши классы звучат немного как StreamReader для MemoryStream . Может быть, вы можете использовать их?

Из документации:

Реализует программу чтения текста, которая считывает символы из потока байтов в определенной кодировке.

Если цель вашего упражнения — выяснить, как это сделать самостоятельно … взгляните на то, как библиотека это сделала. Я думаю, вы найдете этот метод StreamReader.Read() интересным:

Считывает следующий символ из входного потока и продвигает позицию символа на один символ.

Ответ №2:

Существует однозначное соответствие между байтами и символами ASCII, что упрощает обработку байтов как символов. Изменение вашего кода для обработки различных кодировок UNICODE может оказаться непростой задачей. Однако, чтобы ответить на часть вашего вопроса:

Как мне определить, что следующие байты в буфере представляют собой последовательность unicode (utf8 или utf16)? И как мне преобразовать их в char ?

Вы можете использовать System.Text.Encoding класс. Вы можете использовать предопределенные объекты кодирования Encoding.Unicode и Encoding.UTF8 и использовать такие методы, как GetCharCount , GetChars и GetString .

Ответ №3:

Я создал BufferSlice класс, который обертывает буфер byte [] и гарантирует, что используется только назначенный фрагмент. Я также создал пользовательское средство чтения для анализа буфера.

Оказалось, что UTF не является проблемой, поскольку я анализирую буфер только для поиска символов, которые не являются многобайтовыми (пробел, минус, точка с запятой и т.д.). Затем я использую Encoding.GetString от последнего разделителя к текущему, чтобы получить правильную строку обратно.