Есть ли простой способ добавить байт в StringBuffer и указать кодировку?

Вопрос

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

Контекст

Я хочу добавить байт в stringbuffer. Для этого требуется выставить байт на char:

myStringBuffer.append((char)nextByte);

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

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

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

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

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

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

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

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