#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
от последнего разделителя к текущему, чтобы получить правильную строку обратно.