Forum Programmation.autre lecture fichier binaire en fortran et inversion d'octets

Posté par  .
Étiquettes :
0
27
juin
2006
Bonjour,

Je veux utiliser un fichier binaire dans un code fortran en l'ouvrant avec un bout de code que j'ai récupéré

DIMENSION GRID(2500)
INTEGER*2 GRID
open(1,file='19981207RR',form='binary')
read(1,end=99)(GRID(i),i=1,2500)
99 close(1)

mais la personne qui m'envoit le fichier binaire me dit qu'il faut "inverser les octets car le fichier a été généré sur une machine linux".

Kesako ?

Si je lis les fichiers directement avec le bout de code ci-dessus, cela ne correspond pas à ce que je dois obtenir.

Je travaille sur PC, je n'ai pas Linux, et je suis méga débutant en programmation d'où mon appel à l'aide. Merci pour vos conseils

Zoro
  • # Motorola-Intel

    Posté par  . Évalué à 4.

    Tu est victime des indiens, les petits et les grands.
    (joke) en fais le stockage d'un 32bits ou plus en taille peut se faire de deux facons, little-indian et big-endian qui sont la contraction de little-in-the-end et bigger-in-the-end.
    Sur un machine intel (comme ton PC) les deux/quatres octets qui definisse un int (taille a voir en fortran) sont big-endian. Je suppose que la machine linux de ton correspondant travaille en little-indian(mac?).

    Exemple soit la valeur 2335 en decimal qui se traduit en hexa :091F

    dans ton fichier si tu lis octet par octet tu va lire
    09 puis 1F (si le fichier est big indian)
    si tu lis int par int tu va lire
    1F09 a cause le l'inversion

    en plus simple, lis ton fichier octet par octet, determine la taille d'un int du systeme (2 ou 4 octet) et tu fais
    monint= octet[0]*256+octet[1]
    ou
    monint= octet[1]*256+octet[0]
    pour passer d'un systeme a l'autre

    dans ton cas, tu dois lire 1F puis 09
    a transforme par
    monint= octet[1]*256+octet[0]
    pour obtenir 091F
    • [^] # Re: Motorola-Intel

      Posté par  (site web personnel) . Évalué à 2.

      En plus des informations pertinentes du commentaire précédent, suivant le compilateur que tu utilises, tu peux changer la valeur d'une variable d'environnement pour que ton programme marche sans rien y changer :

      Avec le compilateur 'g95', cette variable d'environnement s'appelle G95_ENDIAN, avec le compilateur d'Intel ('ifort'), on peut faire la même chose mais la variable a un nom différent : F_UFMTENDIAN. Quant aux autres compilateurs, renseigne-toi en lisant leur documentation, c'est sûrement possible aussi, mais pas toujours (cf. gfortran).

      Selon l'environnement dans lequel tu te trouves, pour changer les variables d'environnement, il faut faire :
      - avec bash : 'export G95_ENDIAN=LITTLE' ;
      - avec ksh/csh : 'setenv G95_ENDIAN=LITTLE' ;
      - avec DOS : 'set G95_ENDIAN=LITTLE' (enfin, je crois me souvenir, mais mon utilisation du DOS remonte à plusieurs années)...

      Enfin, la plupart des compilateurs permet de choisir à la compilation si la lecture se fera en little ou en big-endian. Souvent, cette option de compilation s'appelle -mlittle-endian ou -mbig-endian. Là encore, pour ton compilateur spécifique vérifie qu'il supporte ces options dans le manuel.

      Dernière remarque : ceci est valable pour du Fortran90. Pour le Fortran77, je n'en sais rien.
      • [^] # Merci

        Posté par  . Évalué à 1.

        Merci LeBreton et Damien pour vos réponse. Je vais mettre en oeuvre vos solutions à mon retour de déplacement. Pour info, mon compilateur fortran est Compac Visual Fortran
        Zoro
  • # Solution

    Posté par  . Évalué à 1.

    Voici la solution que qq m'a proposée sur developpez.net :


    integer*2 grid(2500)
    ...
    open(unit=10, file='19981207RR', access='direct', form='unformatted', recl=5000)
    read(10, rec=1) grid
    close(10)

    c'est tout simple et ça résoud mon pb

    Z

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.