2013-10-27 15 views
5

Sto provando a convertire un byte [] in un float [] inserendo il byte [] in un ByteBuffer, convertendolo in FloatBuffer (.asFloatBuffer) e quindi convertendo questo a un array.UnsupportedOperationException con conversione byte [] in float []

private static float[] toFloatArray(byte[] bytes) { 
    ByteBuffer buffer = ByteBuffer.wrap(bytes); 
    return buffer.asFloatBuffer().array(); 
} 

Tuttavia esecuzione:

byte[] bytes = {14,32,26,21}; 
      toFloatArray(bytes); 

mi dà un java.lang.UnsupportedOperationException at java.nio.FloatBuffer.array(Unknown Source). Credo che la documentazione dice che l'errore ha qualcosa a che fare con il buffer che non viene supportato da un array (???).

Qualcuno ha un'idea su come risolvere il problema, o come DEVO convertire questo array in float?

+0

Sono tentato di pensare che dovresti andare "in profondità" e provare a ottenere un float [] per iniziare invece di un byte []. Escluso questo, è possibile chiamare #getFloat() sul buffer spostato finché non si esaurisce l'input. – Max

risposta

6
private static float[] toFloatArray(byte[] bytes) { 
     ByteBuffer buffer = ByteBuffer.wrap(bytes); 
     FloatBuffer fb = buffer.asFloatBuffer(); 

     float[] floatArray = new float[fb.limit()]; 
     fb.get(floatArray); 


     return floatArray; 
    } 

es:

 byte[] bytes = {65,-56,0,0 , 65,-56,0,0}; 
    float[] result = toFloatArray(bytes); 

    //print 25.0 25.0 
    System.out.println(Arrays.toString(result)); 
+0

Funziona alla grande! Anche l'altra risposta è buona, ma preferisco questa, perché non è richiesto alcun ciclo. – user717572

1

Il modo più semplice per ottenere un float da una matrice byte[] avvolto da un ByteBuffer è quello di utilizzare getFloat() che legge i successivi 4 byte e restituisce il generato float. Puoi farlo in un ciclo, se il tuo byte[] contiene più di 4 byte. Si noti che il metodo genera

BufferUnderflowException - Se ci sono meno di quattro byte rimanenti in questo buffer

si può ottenere dal FloatBuffer così

buffer.asFloatBuffer().get(); 

se vuoi ma array() getta un UnsupportedOperationException se il campo hb dell'istanza è null. Se si guarda il codice sorgente da Oracle JDK 7, c'è un commento

final float[] hb; // Non-null only for heap buffers 

Se si esegue il codice, si noterà l'tornato FloatBuffer è un ByteBufferAsFloatBufferB, non un HeapFloatBuffer.

+0

Ci proverò domani. Ma se lo capisco correttamente, asFloatBuffer() in realtà non converte il tipo, ma cambia solo il modo in cui l'array di byte viene interpretato? – user717572

+0

@user Sembra così. Javadoc afferma 'Crea una vista di questo buffer di byte come un buffer float.' –

+0

Sì, ecco perché provoca un errore quando si" restituisce ByteBuffer.wrap (bytes) .asFloatBuffer(). Array(); " perché veramente i byte sono la memoria allocata. Non può consentire a un array float [] e byte [] di puntare alla stessa memoria. – Tatarize

0
public static float[] toFloatArray(byte[] bytes) { 
    float[] floats = new float[bytes.length/4]; 
    ByteBuffer.wrap(bytes).asFloatBuffer().get(floats).array(); 
    return floats; 
} 

Il motivo per cui non si può fare return ByteBuffer.wrap(bytes).asFloatBuffer().array(); è che crea una visione di questo buffer di byte come un buffer galleggiante. Il che significa che sta usando la stessa memoria. È veloce, ma ha bisogno di un posto per metterlo in memoria che non viene trattato come un float [] AND byte [], quindi perché non può restituire i dati senza nuova memoria.

public static void convertFloatArray(byte[] bytes, float[] floats) { 
    ByteBuffer.wrap(bytes).asFloatBuffer().get(floats,0,bytes.length/4); 
} 

E 'solo la classe non ha una propria memoria, ma giocherella con la memoria si dà, che è impressionante, ma potrebbe essere confuso, a volte.