Быстрый ByteBuffer для CharBuffer или char [] - PullRequest
5 голосов
/ 09 мая 2011

Какой самый быстрый способ конвертировать java.nio.ByteBuffer a в (недавно созданный) CharBuffer b или char[] b.

При этом важно, чтобы a[i] == b[i]. Это означает, что не a[i] и a[i+1] вместе не составляют значение b[j], что getChar(i) будет делать, но значения должны быть "распространены".

byte a[] = { 1,2,3, 125,126,127, -128,-127,-126 } // each a byte (which are signed)
char b[] = { 1,2,3, 125,126,127,  128, 129, 130 } // each a char (which are unsigned)

Обратите внимание, что byte:-128 имеет те же (младшие 8) биты, что и char:128. Поэтому я полагаю, что «лучшая» интерпретация будет такой, как я отметил выше, поскольку биты одинаковы.

После этого мне также нужен перевод наоборот : самый эффективный способ вернуть char[] или java.nio.CharBuffer обратно в java.nio.ByteBuffer.

Ответы [ 3 ]

12 голосов
/ 09 мая 2011

Итак, что вы хотите - конвертировать, используя кодировку ISO-8859-1.

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

CharBuffer result = Charset.forName("ISO-8859-1").decode(byteBuffer);

Другое направление будет:

ByteBuffer result = Charset.forName("ISO-8859-1").encode(charBuffer);

Пожалуйста, сравните это с другими решениями. (Чтобы быть справедливым, часть Charset.forName не должна быть включена, а также должна выполняться только один раз, а не для каждого буфера снова.)

Начиная с Java 7 также существует класс StandardCharsets с предварительно созданными экземплярами Charset, поэтому вы можете использовать

CharBuffer result = StandardCharsets.ISO_8859_1.decode(byteBuffer);

и

ByteBuffer result = StandardCharsets.ISO_8859_1.encode(charBuffer);

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

5 голосов
/ 09 мая 2011

Я бы согласился с @ Ishtar's, предлагая вообще не переходить на новую структуру и конвертировать только по мере необходимости.

Однако, если у вас есть куча байтового буфера, вы можете сделать.

ByteBuffer bb = ...
byte[] array = bb.array();
char[] chars = new char[bb.remaining()];
for (int i = 0; i < chars.length; i++)
    chars[i] = (char) (array[i + bb.position()] & 0xFF);
0 голосов
/ 05 июня 2011

Помимо отсрочки создания CharBuffer, вы можете обойтись и без него.Если коду, использующему данные в качестве символов, не требуется строго CharBuffer или char [], просто выполните простое преобразование на лету;используйте ByteBuffer.get () (относительный или абсолютный), преобразуйте в char (примечание: как указано, вы ДОЛЖНЫ, к сожалению, явно маскировать вещи; в противном случае значения 128-255 будут расширены до неправильных значений, 0xFF80 - 0xFFFF;7-битный ASCII) и используйте его.

...