Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast ByteBuffer to CharBuffer or char[]

What is the fastest method to convert a java.nio.ByteBuffer a into a (newly created) CharBuffer b or char[] b.

By doing this it is important, that a[i] == b[i]. This means, that not a[i] and a[i+1] together make up a value b[j], what getChar(i) would do, but the values should be "spread".

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)

Note that byte:-128 has the same (lower 8) bits as char:128. Therefore I assume the "best" interpretation would be as I noted it above, because the bits are the same.

After that I also need the vice versa translation: The most efficient way to get a char[] or java.nio.CharBuffer back into a java.nio.ByteBuffer.

like image 400
towi Avatar asked May 09 '11 11:05

towi


People also ask

What is the byte order of ByteBuffer?

By default, the order of a ByteBuffer object is BIG_ENDIAN. If a byte order is passed as a parameter to the order method, it modifies the byte order of the buffer and returns the buffer itself. The new byte order may be either LITTLE_ENDIAN or BIG_ENDIAN.

How do I write ByteBuffer to a file?

File access with FileChannel + ByteBuffer To write data into a FileChannel or read from it, you need a ByteBuffer . Data is put into the ByteBuffer with put() and then written from the buffer to the file with FileChannel. write(buffer) . FileChannel.

How do I allocate ByteBuffer?

A new ByteBuffer can be allocated using the method allocate() in the class java. nio. ByteBuffer. This method requires a single parameter i.e. the capacity of the buffer.

Which method is used to create a ByteBuffer?

A direct byte buffer may be created by invoking the allocateDirect factory method of this class.


2 Answers

So, what you want is to convert using the encoding ISO-8859-1.

I don't claim anything about efficiency, but at least it is quite short to write:

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

The other direction would be:

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

Please measure this against other solutions. (To be fair, the Charset.forName part should not be included, and should also be done only once, not for each buffer again.)

From Java 7 on there also is the StandardCharsets class with pre-instantiated Charset instances, so you can use

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

and

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

instead. (These lines do the same as the ones before, just the lookup is easier and there is no risk to mistype the names, and no need to catch the impossible exceptions.)

like image 194
Paŭlo Ebermann Avatar answered Sep 29 '22 13:09

Paŭlo Ebermann


I would agree with @Ishtar's, suggest to avoid converting to a new structure at all and only convert as you need it.

However if you have a heap ByteBuffer you can do.

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);
like image 32
Peter Lawrey Avatar answered Sep 29 '22 13:09

Peter Lawrey