IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Fortran Discussion :

[Fortran 90] Écriture/lecture fichier binaire accès direct


Sujet :

Fortran

  1. #1
    Membre du Club
    Inscrit en
    Février 2004
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 79
    Points : 57
    Points
    57
    Par défaut [Fortran 90] Écriture/lecture fichier binaire accès direct
    J'essaie d'écrire un fichier binaire en Fortran, et ensuite le lire en VB.Net 2.0.

    Je débute avec le binaire, et fortran j'y connais pas grand chose.

    Supposons le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=8)
        WRITE(n_unit, rec=1) 3.43d0, 23.7D0
        CLOSE(n_unit)
    Ca je n'ai aucun problème à récupérer mes deux nombres en vb.net (que ce soit en lisant les 2 nombres un après l'autre, ou bien par accès direct au 2e nombre)


    Par contre, si je fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=8)
        WRITE(n_unit, rec=1) 3.43d0
        WRITE(n_unit, rec=9) 23.7d0
        CLOSE(n_unit)
    Je peux juste récupérer mon 3.43, mais à la place de 23.7, j'obtient 0.


    voici le code j'utilise en vb.net pour récupérer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    FileOpen(ff, "c:\toto.txt", OpenMode.Binary, OpenAccess.Read)
    FileGet(ff, d1)
    FileGet(ff, d2)
    FileClose(ff)
    Ou encore pour un accès direct à la 2e valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FileOpen(ff, "c:\toto.txt", OpenMode.Binary, OpenAccess.Read)
    FileGet(ff, d2, 9)
    FileClose(ff)
    Mes deux codes en vb fonctionne pour récupérer ce que j'ai écris en fortran de la première facon, mais ca ne fonctionne pas pour la deuxième méthode.

    qq'un peut m'aider? Merci

  2. #2
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Le rec dans write n'est pas en octets, mais en "numero d'enregistrement".
    Lorsque tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        WRITE(n_unit, rec=1) 3.43d0
        WRITE(n_unit, rec=9) 23.7d0
    tu ecris la premiere valeur a l'enregistrement numero 1 (les 8 premiers octets), la deuxieme valeur a l'enregistrement numero 9 (octets 64 a 72). Dans les enregistrements 2 a 8, il y a n'importe quoi (des zeros, la plupart du temps).
    La bonne utilisation est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        WRITE(n_unit, rec=1) 3.43d0
        WRITE(n_unit, rec=2) 23.7d0
    Une facon simple de s'apercevoir du probleme est de regarder si la taille de ton fichier est celle attendue (deux fois 8 octets: 16 octets, et non 9 fois 8 octets = 72 octets comme obtenu avec la deuxieme methode).

  3. #3
    Membre du Club
    Inscrit en
    Février 2004
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 79
    Points : 57
    Points
    57
    Par défaut
    Merci de ta réponse,

    Mais ça ne fonctionne pas tout à fait, quoiqu'avec ton aide j'ai réussi à le faire fonctionner, je ne comprends toujours pas la logique derriere parce pour que ca marche, voici ce que je dois faire

    Pour des valeurs double précision, afin d'avoir un fichier de 16 octets selon les deux méthodes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    !    OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=4)
    WRITE(n_unit, rec=1) double1, double2
    CLOSE(n_unit) 
     
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=2)
        WRITE(n_unit, rec=1) double1
        WRITE(n_unit, rec=2) double2
        CLOSE(n_unit)
    Je dois donc, dans le 2e façon, mettre le "recl" = 2 si je veux qu'il écrive ma valeur à partir du 8e octet quand je fait rec=2.
    Par contre, si je met recl=2 dans la première méthode, ça plante.

    Et là, si je veux à la place, écrire des variables entières:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    !    OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=2)
    !    WRITE(n_unit, rec=1) entier1, entier2
    !    CLOSE(n_unit) 
     
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', access='direct', recl=1)
        WRITE(n_unit, rec=1) entier1
        WRITE(n_unit, rec=2) entier2
        CLOSE(n_unit)
    je dois mettre recl=2 ou recl=1 selon le cas, afin d'avoir des fichiers de 8 octets, et non plus 16.

    Bref, je ne comprends pas trop ce que représente exactement le recl? Est-ce quatre fois le nombre d'octet qui sera écrit à chaque fois avec WRITE? Je pensais que c'était le nombre d'octet directement... et après quand je fait WRITE, le rec=2 correspond en fait à la position:
    rec*recl*2 en octet? ou bien c'est rec*(nombre d'octets de la variable à écrire) ?

    C'est pas un peu barbare quand on veut écrire et manipuler des fichiers avec plusieurs types de variables?

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Quel compilateur utilise tu ?

    En Fortran, il y a un concept de taille de storage par défaut. Il doit être le même pour les reals et les integers, et le double pour les doubles... Le concept d'octet n'existe pas.

    Certains compilateurs définissent le recl en octets, d'autres en unité de storage.

    Tes exemples semblent montrer que le tien s'attend à des unités de storage. Tu dois dans ce cas utiliser un recl de 1 pour des integers et des reals, et de 2 pour des doubles.

  5. #5
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    En Fortran, il y a un concept de taille de storage par défaut. Il doit être le même pour les reals et les integers, et le double pour les doubles... Le concept d'octet n'existe pas.
    En effet, recl est en unite 'dependant du processeur' pour les I/O unformatted. Cette precaution de langage est surtout due au fait que la longueur d'un type varie d'un processeur a l'autre. Dans l'immense majorite des cas, on peut considerer sans se tromper que recl est en octets. A voir dans la doc du compilo, quand meme. Mais ceux que j'ai utilise (f77, g77, ifc, pgf90) attendent des octets.

    MatP - Donc si tu veux creer un fichier binaire contenant des double-precision qui font, sur ta machine, 8 octets, utilises un recl=8 (4 pour des entiers ou des reels 32 bits, etc.).
    Ensuite tous les records seront de la meme longueur, et on se place dans le record number que l'on veut (en general, les uns a la suite de l'autre!).
    Dans ton cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', 
       &                   access='direct', recl=8)
        WRITE(n_unit, rec=1) double1
        WRITE(n_unit, rec=2) double2
        CLOSE(n_unit)
    Cela produira bien un fichier de 16 octets. Pour des entiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        OPEN(unit=n_unit, file='C:\toto.txt', form='unformatted', 
       &         access='direct', recl=4)
        WRITE(n_unit, rec=1) entier1
        WRITE(n_unit, rec=2) entier2
        CLOSE(n_unit)
    Ici, le fichier fera evidemment 8 octets.

    C'est pas un peu barbare quand on veut écrire et manipuler des fichiers avec plusieurs types de variables?
    C'est tres penible. Le plus simple est de tout mettre dans le meme type (le plus grand) ou utiliser un langage comme le C qui est plus adepte a l'I/O que le Fortran (le coeur du programme peut quand meme rester en Fortran).

  6. #6
    Membre du Club
    Inscrit en
    Février 2004
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 79
    Points : 57
    Points
    57
    Par défaut
    J'utilise le compilateur Fortran d'Intel.

    Mais là, j'ai remarqué que mon compilateur supportait le form='Binary' et avec access='Append', dans ce cas, il va ajouter à la fin du fichier toujours le nombre d'octets auxquels corresponds les variables, pas besoin de rec et de recl.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    OPEN(unit=1, file='C:\toto.txt', form='binary', access='sequential')
    WRITE(1) double1, entier1, double2
    CLOSE(1)
    Dans ce cas, mon fichier va être de 20 octets.
    et je peux utiliser access='append' à la place aussi, si je veux ajouter directement à la fin du fichier, sans avoir à préciser la fin de mon fichier avec rec='X'.

    Dans le fond, le access='direct', j'en ai juste besoin quand je lis le fichier, pas quand je l'écris, et je le lis avec un programme Vb.net, et en vb, si j'ouvre avec acces direct, faut que je précise à quel octet commencer à lire.

    Mais merci pour les précisions sur les "unités de storages"!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VS2005]lecture/écriture dans fichier binaire
    Par shadowmoon dans le forum Windows Forms
    Réponses: 10
    Dernier message: 25/09/2007, 17h30
  2. Lecture fichier binaire et inversion d'octets
    Par zoro_le_renard dans le forum Fortran
    Réponses: 8
    Dernier message: 17/07/2007, 20h35
  3. Lecture fichier binaire
    Par djidji dans le forum Langage
    Réponses: 1
    Dernier message: 09/11/2006, 11h58
  4. Lecture fichier binaire
    Par kek_net dans le forum Langage
    Réponses: 5
    Dernier message: 07/08/2006, 19h37
  5. Lecture fichier binaire
    Par gabule dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 30/05/2006, 15h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo