2011-05-09 7 views
5

¿Cuál es el método más rápido para convertir un java.nio.ByteBuffer a en un (recién creado) CharBuffer b o char[] b.Fast ByteBuffer a CharBuffer o char []

Al hacerlo, es importante que a[i] == b[i]. Esto significa que no a[i] y a[i+1] juntos componen un valor b[j], lo que getChar(i) haría, pero los valores deberían ser "extendidos".

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) 

Nota que byte:-128 tiene los mismos (inferiores 8) bits como char:128. Por lo tanto, supongo que la "mejor" interpretación sería como lo mencioné anteriormente, porque los bits son los mismos.

Después de eso, también es necesario el viceversa traducción: La forma más eficiente para conseguir un char[] o java.nio.CharBuffer de nuevo en un java.nio.ByteBuffer.

+3

¿Qué quieres hacer con este búfer de char? ¿Qué debería pasar si pones un char de 2 bytes? ¿Cómo debería verse la matriz de bytes traducidos? Dependiendo de lo que necesite, la forma más eficiente podría ser no convertirlo en absoluto. – Ishtar

+1

En otras palabras, ¿está buscando interpretar los contenidos del 'ByteBuffer' como una secuencia de caracteres codificados usando ISO-8859-1? – Anon

+0

La suposición es que no hay ningún valor mayor que '0xff' en el búfer' char [] 'para back-translation. Cualquier comportamiento/bloqueo estaría bien ("no especificado"). ISO-8859-1? Por lo que sé, hay bytes que no pueden ser traducidos por ninguna página de códigos (por ejemplo '\ 0')? Creo que las numerosas bibliotecas de conversión de páginas de códigos no lo toman muy bien si se descarga un flujo de datos de 8 bits. Pero no sé sobre Java, lo buscaré. Imagina que tengo datos de imagen/imagen. – towi

Respuesta

11

Entonces, lo que desea es convertir utilizando la codificación ISO-8859-1.

no reclamo nada acerca de la eficiencia, pero al menos es bastante corto para escribir:

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

La otra dirección sería:

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

favor, medir este frente a otras soluciones. (Para ser justos, la parte Charset.forName no debería incluirse, y también debe hacerse sólo una vez, no para cada búfer de nuevo.)

De Java 7 en la que también es la clase StandardCharsets con instancias pre-instanciado charset, por lo puede utilizar

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

y

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

lugar. (Estas líneas hacen lo mismo que las anteriores, solo la búsqueda es más fácil y no hay riesgo de escribir mal los nombres, y no es necesario capturar las excepciones imposibles).

+1

java.nio.StandardCharsets.ISO_8859_1 y sus pares proporcionan una referencia simple al conjunto de caracteres sin búsqueda de cadenas o excepciones arrojadizas. – davenpcj

+0

Gracias por la nota, actualicé la respuesta. –

6

Estoy de acuerdo con @ Ishtar, sugiero evitar convertir a una nueva estructura y convertir solo cuando lo necesite.

Sin embargo, si tiene un montón de ByteBuffer que puede hacer.

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

Ok, eso es genérico y seguro . Gracias. Pero espero que haya una llamada API para eso? – towi

+0

Puede estar seguro de que la codificación funciona de la manera que desee. Puede probar "US-ASCII", pero no sé si funciona para 0 - 255. –

+1

No, US-ASCII es solo para 0-127, otros bytes están mapeados (en Java, cuando no se utiliza la API CharSet para control más fino) a ''?'', otros caracteres a '(byte) '?''. Use ISO-8859-1 para una cobertura completa del rango de 8 bits, es decir, para hacer lo que hace su ciclo. –

0

Además de diferir la creación de CharBuffer, puede ser capaz de vivir sin uno. Si el código que utiliza datos como caracteres no necesita estrictamente un CharBuffer o un char [], simplemente realice una conversión simple sobre la marcha; use ByteBuffer.get() (relativo o absoluto), conviértalo en char (nota: como se indicó, DEBE, lamentablemente, enmascarar cosas explícitamente; de ​​lo contrario, los valores 128-255 se extenderán a valores incorrectos, 0xFF80 - 0xFFFF; no son necesarios para ASCII de 7 bits), y usar eso.