|
|||||||
|
|
|
![]() |
|
|
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 09: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: 13:32.



















