Есть ли простой способ добавить байт в StringBuffer и указать кодировку? - PullRequest
11 голосов
/ 21 апреля 2011

Вопрос

Какой самый простой способ добавить байт в StringBuffer (то есть преобразовать байт в символ) и указать используемую кодировку символов (ASCII, UTF-8 и т. Д.)?

Context

Я хочу добавить байт в буфер строк.Для этого необходимо преобразовать байт в символ:

myStringBuffer.append((char)nextByte);

Однако в приведенном выше коде используется кодировка символов по умолчанию для моей машины (MacRoman).Между тем, другие компоненты в системе / сети требуют UTF-8.Поэтому мне нужно что-то вроде:

try {
    myStringBuffer.append(new String(new Byte[]{nextByte}, "UTF-8"));
} catch (UnsupportedEncodingException e) {
    //handle error
}

Что, честно говоря, довольно некрасиво.

Конечно, есть лучший способ (кроме разбиения одного и того же кода на несколько строк) ???????

Ответы [ 2 ]

16 голосов
/ 21 апреля 2011

Простой ответ - «нет».Что если байт является первым байтом многобайтовой последовательности?Ничто не будет поддерживать состояние.

Если у вас есть все байты логического символа в руке, вы можете сделать:

sb.append(new String(bytes, charset));

Но если у вас есть один байт UTF-8, выне может сделать это вообще с классами stock.

Не было бы очень сложно создать сокрушенный StringBuffer, который использует классы java.nio.charset для реализации добавления байтов, но это не будет один илидве строки кода.

Комментарии указывают на то, что здесь необходимы базовые знания Unicode.

В UTF-8 'a' - один байт, 'á' - два байта, '丧'это три байта, а '?' это четыре байта.Задача CharsetDecoder - преобразовать эти последовательности в символы Unicode.Рассматриваемый как последовательная операция над байтами, это, очевидно, процесс с отслеживанием состояния.

Если вы создаете CharsetDecoder для UTF-8, вы можете передавать его только байтом за раз (в ByteBuffer) через этот метод .Символы UTF-16 будут накапливаться на выходе CharBuffer.

3 голосов
/ 21 апреля 2011

Я думаю, что здесь ошибка в том, что мы имеем дело с байтами вообще. Вместо этого вы хотите работать со строками символов.

Просто вставьте считыватель в поток ввода и вывода, чтобы сделать отображение между байтами и символами для вас. Тем не менее, используйте форму конструктора InputStreamReader(InputStream in, CharsetDecoder dec) для ввода, чтобы вы могли обнаруживать ошибки кодирования ввода через исключение. Теперь у вас есть строки символов вместо буферов байтов. Положите OutputStreamWriter на другом конце.

Теперь вам больше не нужно беспокоиться о байтах или кодировках. Так намного проще.

...