Bonjour,
je travaille actuellement sur une chaine de traitement dont une composante (écrite en c) effectue la lecture d'un fichier binaire et en extrait des valeurs double à partir de 2 octets,
je vous mets une version simplifiée ici (normalement, les valeurs sont écrites dans une matrice de valeurs, les variables globales ont été initialisés avec des valeurs bidons pour les tests: Coeffp = 0.01 et nbLus = 200):
/** remplit le tableau PLUIE1 avec les valeurs presentes dans le tableau
* en les multipliant avec le coefficient defini par la variable CoeffP
* @param filLu : flux du fichier
*/
int remplirPLUIE1(FILE* filLu){
int i=0, j=0;
unsigned short valLu;
char *val = (char *)calloc( sizeof(unsigned short)+1, sizeof(char));
float valeur;
printf(" CoeffP == %f\n",CoeffP);
/* Parcours du fichier en lecture */
rewind (filLu);
fread(&valLu, sizeof(unsigned short), 1, filLu);
for(i=0; i<nbLus && !feof(filLu); i++){
sprintf(val, "%d", valLu); // on prend la valeur sur 2 octets
valeur = atoi(val)*CoeffP; // le coeff est en flottant
printf("%f\n",valeur); // on affiche
fread(&valLu, sizeof(unsigned short), 1, filLu);
}
return 0;
}
le probleme, c'est que je voudrais faire cette lecture dans le programme principal (java)
j'ai donc fait quelques petits tests comme par exemple:
/**
* effectue la lecture d'un fichier binaire et extrait les données dans une Observation
* @param fichierBinaire: l'uri du fichier binaire
* @return une Observation
*/
public static void lireFichierBinaire(String fichierBinaire) {
DataInputStream in = null;
System.out.println(" lecture du fichier binaire " + fichierBinaire);
System.out.println(" CoeffP == " + CoeffP);
System.out.println(" lireFichierBinaire");
try {
// on crée un input stream de bytes
in = new DataInputStream(new FileInputStream(fichierBinaire));
// le compteur (sert à se reperer dans la liste des capteurs)
int compteur = 0;
char c;
// on lit les octets 2 par 2
while (compteur < nbLus && (c = in.readChar()) != -1) {
System.out.println("" + ((double) (int)c * CoeffP));
compteur++;
}
} catch (IOException ex) {
System.out.println(ex);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
System.out.println(ex);
}
}
}
mais les resultats ne concordent pas, savez vous par hasard quelles modifications sont à apporter à cette fonction pour que ca marche ?
j'ai aussi essayé ca:
/**
* effectue la lecture d'un fichier binaire et extrait les données dans une Observation
* @param fichierBinaire: l'uri du fichier binaire
* @return une Observation
*/
public static void lireFichierBinaire2(String fichierBinaire) {
DataInputStream in = null;
System.out.println(" lecture du fichier binaire " + fichierBinaire);
System.out.println(" CoeffP == " + CoeffP);
System.out.println(" unsignedByteToInt1");
try {
// on crée un input stream de bytes
in = new DataInputStream(new FileInputStream(fichierBinaire));
byte[] byteArray = new byte[2];
// le compteur (sert à se reperer dans la liste des capteurs)
int compteur = 0;
// on lit les octets 2 par 2
while (compteur < nbLus && in.read(byteArray) != -1) {
System.out.println("" + ((double) byteArrayToInt(byteArray) * CoeffP));
compteur++;
}
} catch (IOException ex) {
System.out.println(ex);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
System.out.println(ex);
}
}
}
private static int byteArrayToInt(byte[] byteArray) {
int total = 0;
// for (int i = 0; i < byteArray.length; i++) {
// total += ((byteArray.length - i) * 255) * byteArray[i] / 255;
// }
// total = byteArray[0] * byteArray[1];
int a = unsignedByteToInt(byteArray[0]);
int b = unsignedByteToInt(byteArray[1]);
System.out.print(""+byteArray[0]+" "+byteArray[1]+" "+a+" "+b+" >> ");
// total = a*255 + b;
total = byteArray[0] * byteArray[1];
return total;
}
/**
* effectue la conversion d'un byte en int en traitant le byte comme unsigned
* @param b
* @return
*/
private static int unsignedByteToInt(byte b){
int res = (int)b;
if (res < 0){
res = 128 + (128 + res); // voir complément à deux
}
return res;
}mais les résultats sont également erronés par rapport aux résultats obtenus avec la focntion c...
les fonctions tests ainsi qu'un fichier binaire sont accesibles ici:
[url]
http://benjbb3sp.free.fr/lecture%20binaire/
[/url]


Je n'ai pas lu ton code, mais as tu pensé que très probablement les valeurs sont codées en little endian en C et que de son côté, Java code en Big endian ?
effectivement, les fichiers binaires étaient encodés en little endian, alors que la jvm ne traite que du big endian, en faisant quelques petits bidouillages, j'ai reussi à résoudre mon probleme
voila ce que ca donne:
public static final float CoeffP = 0.01f; public static final int nbLus = 200; /** * @param args the command line arguments */ public static void main(String[] args) { if (args.length > 0) { System.out.println("start"); lireFichierBinaire(args[0]); System.out.println("The End"); } else { System.out.println("Not Enough arguments"); } } /** * fonction test de lecture d'un fichier .dat * @param fichierBinaire: l'uri du fichier binaire */ public static void lireFichierBinaire(String fichierBinaire) { DataInputStream in = null; System.out.println(" lecture du fichier binaire " + fichierBinaire); System.out.println(" CoeffP == " + CoeffP); try { // on crée un input stream de bytes in = new DataInputStream(new FileInputStream(fichierBinaire)); byte[] byteArray = new byte[2]; // le compteur (sert à se reperer dans la liste des capteurs) int compteur = 0; // on lit les octets 2 par 2 while (compteur < nbLus && in.read(byteArray) != -1) { System.out.println("" + ((double) byteArrayToInt(byteArray) * CoeffP)); compteur++; } } catch (IOException ex) { System.out.println(ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { System.out.println(ex); } } } /** * extrait la valeur int d'un byte array en little endian * @param byteArray: un byte array en ordre little endian * @return int */ private static int byteArrayToInt(byte[] byteArray) { int total = 0; for (int i = 0; i < byteArray.length; i++) { total += unsignedByteToInt(byteArray[i]) * ((i*256) == 0 ? 1 : i*256); } return total; } /** * effectue la conversion d'un byte en int en traitant le byte comme s'il était unsigned * @param b: le byte * @return la valeur int du byte comme s'il était unsigned */ private static int unsignedByteToInt(byte b){ int res = (int)b; if (res < 0){ res = 256 + res; // voir complément à deux } return res; }et ici deux (parties de ) traces de l'exectution du programme test en c et de celui ci avec le même fichier binaire en parametre
start Lecture du fichier binaire pd04-199409212054.dat CoeffP == 0.010000 0.000000 0.000000 0.000000 0.000000 5.040000 5.040000 0.000000 0.000000 0.000000 0.000000start lecture du fichier binaire pd04-199409212054.dat CoeffP == 0.01 0.0 0.0 0.0 0.0 5.039999887347221 5.039999887347221 0.0 0.0 0.0 0.0j'ai un petit décalage de valeur mais ce n'est pas tres genant vu que ce sont des valeurs millimetres