|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
|
[JAVA] Lettura dati binari interi a 32-bit
Ciao,
vorrei un consiglio per leggere in JAVA dei dati binari in uscita da un AD converter di uno strumento di misura. Non conosco molto bene il linguaggio e la difficoltà principale che incontro è nella corretta lettura del formato binario. Lo strumento è basato su piattaforma Intel x86, quindi i dati sono salvati in memoria in formato little-endian come signed int a 32 bit. Ho tentato vari approcci con DataInputStream, BufferedReader, metodo read() diretto... ma non riesco ad ottenere una lettura corretta: ottengo valori pazzi, molto alti o zero, quando il contenuto del file binario è di altro tipo. Esiste una macro interna allo strumento che esporta i dati in formato ASCII e dal confronto mi rendo conto dell'errore. Questa è la classe ReadBin che ho tentato di utilizzare: Codice:
// ReadBin.java import java.io.DataInputStream; import java.io.FileInputStream; public class ReadBin { public static void main(String args[]) { try { // Crea un data input stream FileInputStream fis = new FileInputStream("fileName.dat"); DataInputStream dis = new DataInputStream(fis); // Legge i primi venti dati dallo stream for (int t=0; t<20; t++) System.out.println(dis.readByte()); // Chiude il file input stream fis.close(); } catch (Exception e) { System.out.println("Exception: " + e); } } } Al seguente LINK è reperibile il file fileName.zip che contiene il file binario (fileName.dat) e il file in formato ascii (fileName.txt). http://dl.dropbox.com/u/21541796/fileName.zip Grazie per ogni buon lume ![]() DD
__________________
Alla povertà mancano molte cose, all'avarizia tutte. Ultima modifica di DeltaDirac : 27-03-2011 alle 08:12. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
In ObjectInputStream c'è una funzione che permette di leggere gli int. Non ricordo però se li legge big-endian o little-endian. Prova e vedi se i valori sono corretti.
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
L'ordine dei byte in datainputstream è quello di java (big endian).
Strano a dirsi ma una valida alternativa è FileImageInputStream. Codice:
FileImageInputStream fin = new FileImageInputStream(new File("filename.dat")); fin.setByteOrder(ByteOrder.LITTLE_ENDIAN); for(int i = 0; i < 20; i++) { int numero = fin.readInt(); }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
|
Quote:
Questo è il nuovo link in cui compaiono entrambi i file (binario e formato testo) con le dimensioni corrette. Venendo al nocciolo della questione: tu dici che l'ordine dei byte in JAVA è big-endian. E' un'asserzione notevole, e l'unica spiegazione che vedo e nella gestione del formato dei dati operato dalla JVM che per qualche ragione è diversa da quella nativa della CPU Intel (little endian). Ma nella documentazione non sono riuscito a scovare questa informazione; mi puoi indicare dove trovarla? Comunque confermo: usando la classe FileImageInputStream tutto funziona a dovere. Grazie ![]() Ovviamente occorre importare correttamente i pack e le classi relative. Ho modificato il sorgente così: Codice:
// ReadBin.java import java.io.File; import javax.imageio.stream.FileImageInputStream; import java.nio.ByteOrder; public class ReadBin { public static void main(String args[]) { try { // Crea un FileImage input stream FileImageInputStream fis = new FileImageInputStream(new File("fileName.dat")); // Converte in LITTLE_ENDIAN fis.setByteOrder(ByteOrder.LITTLE_ENDIAN); // Legge i primi venti dati dallo stream for (int t=0; t<20; t++) System.out.println(fis.readInt()); // Chiude il file input stream fis.close(); } catch (Exception e) { System.out.println("Exception: " + e); } } } Grazie ancora.
__________________
Alla povertà mancano molte cose, all'avarizia tutte. |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
La jvm è big-endian per via del capitolo 3.11 delle sue specifiche (operandi multibyte).
Per quanto riguarda il linguaggio, sebbene sia comunemente considerato big-endian solo per convenzione, l'ordine è - a mio sommessissimo parere - chiaramente espresso nelle specifiche del linguaggio (3.10.1) relativamente alle corrispondenze esadecimale-decimale - i corrispondenti esadecimali degli interi multibyte sono tutti big-endian. Presumo che la ragione dipenda dal fatto che java è nato come strumento per il web e che quindi si sia scelto di adottare il formato "network byte order", cioè il big endian.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
|
Prefetto, grazie!
__________________
Alla povertà mancano molte cose, all'avarizia tutte. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 05:08.