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 :

Temps d'accès fichier binaire


Sujet :

Fortran

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut Temps d'accès fichier binaire
    Bonjour à tous,


    J'ai une question concernant la rapidité (temps d'accès) en lecture sur les fichiers.

    J'ai des fichiers binaires (écrits ligne par ligne par la même machine, quelques milliers de lignes) que j'arrive très bien à relire de la même manière, ligne par ligne avec un READ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          i=1
      12  READ(KF,END=11) V1(i),V2(i),V3(i)
          i=i+1
          goto 12
      11  CLOSE(KF)
    (En vrai j'ai 25 et non pas 3 "colonnes", mais pour l'exemple c'est suffisant )

    (pour référence : il y a 4 octets de header et 4 octets de trailer pour chaque ligne, donc en fait 26*8 octets par ligne)

    Est-ce qu'en lisant les fichiers ainsi, je ne me paie bien le temps d'accès au fichier (temps d'accès hdd, PLUS éventuellement temps d'accès réseau si fichier sur ressource externe) qu'une seule fois (lors de l'open), ou à chaque ligne (à chaque read) ?

    En fait je constate un gros écart entre un fichier en local et un fichier sur ressource réseau, mais l'écart me semble trop fort pour être dû à un unique temps d'accès réseau : grosso modo <0.1s de lecture en local => 0.3s de lecture en réseau, pour un fichier de 1 Mo. (en valeur absolue cela semble peu mais je vais ensuite aller lire de nombreux fichiers, donc au bout du compte c'est pas du tout négligeable)

    Pour tester, j'ai aussi lancé le bout de code suivant (pour un fichier de 4927 lignes, 25 colonnes de 8 octets chacune, + 4 octets de header et de trailer à chaque ligne, soit 26*8 octets par ligne, donc 4927*26*8 octets en tout) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
          integer*8 ibin(4927*26)
     
          ...
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED',RECL=4927*26*8)
          READ(KF,REC=1) ibin
    Cette implémentation ne coûte quant à elle que 0.13s, soit à peu près moitié moins que la première. Sauf erreur (j'ai bien lu et récupéré l'intégralité du fichier ?), j'en déduis donc que la boucle sur READ n'est pas terrible, mais je ne sais pas comment la remplacer efficacement.

    Là j'ai réussi à produire un exemple, mais je ne sais pas comment retrouver mes valeurs d'origine à partir de mon ibin (plus généralement je me dis qu'il y a sûrement mieux et/ou beaucoup plus simple).

    Merci pour votre aide

  2. #2
    Membre régulier Avatar de moomba
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 134
    Points : 104
    Points
    104
    Par défaut
    En principe, cette lecture est optimisée par le compilateur qui vas lire la tranche d'un seul coup. Mais j'ai un doute dans ton cas car la syntaxe est vielle (Fortran 77 ?).

    Si tu peut utiliser du Fortran 90, je recommande fortement l'écriture brute de coffre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          WRITE(KF) V1,V2,V3
          CLOSE(KF)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          READ(KF) V1,V2,V3
          CLOSE(KF)
    Si tu as besoin de le lire qu'une partie, découpe les tableaux sur plusieurs lignes, et ne lis que la partie qui t’intéresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          WRITE(KF) V1
          WRITE(KF) V2
          CLOSE(KF)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          READ(KF) V1(1:11)
          CLOSE(KF)
    Cet accès est optimum, du moins en posix. Utilises tu des ressources distribuées (MPI en l’occurrence) ? Si oui, tu peut essayer des ressources évoluées type PHDF5 ou PNETCDF, puis tuner la couche MPI-IO. Mais je recommande le posix bourrin, comme vue au dessus. Les perfs sont excellents si le système de fichier tient le coup, et on se rapproche d'un MPI-IO tuné sans les ennuis.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Salut moomba,

    merci beaucoup pour ta réponse (arrivée pendant que j'éditais). Je ne connaissais pas ces syntaxes, je vais essayer. La première devrait effectivement résoudre le problème si le compilo fait ce qu'il faut.

    Si la partie read permet bien la lecture du fichier en l'état, car je ne peux en revanche pas changer la méthode d'écriture de ces fichiers.

    Edit :

    J'ai testé ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          OPEN(KF,FILE='fichier',FORM='UNFORMATTED')
          READ(KF,END=110) V1,V2,V3
     110  CLOSE(KF)
    (en adaptant à ma situation bien sûr, j'ai V1,V2 etc jusque V25) sur un fichier en l'état. Il semble planter à la fin du fichier puisqu'il me renvoie

    Fortran runtime error: I/O past end of record on unformatted file
    (idem avec ou sans le END)

    Je précise au cas où : mon compilo est gcc 4.8.1 64bits, et que je suis sous W7 64bits.

    J'ai essayé en déclarant V1,... d'avance avec la bonne taille, ça n'a rien changé.

    (ah, sinon, pour les aspects posix/MPI, etc, on est complètement en-dehors de mon domaine de compétence (et de juridiction), je ne connais même pas les termes )

  4. #4
    Membre régulier Avatar de moomba
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 134
    Points : 104
    Points
    104
    Par défaut
    Effectivement, nous nous sommes croisé

    As tu les sources de la façon dont les fichiers sont écris, et si oui peut tu poster la section de code correspondante ? Si tu ne peut vraiment pas les modifier, il faut savoir exactement comment c'est écrit.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Oui, pas de problème.

    Ces fichiers sont ouverts une fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          OPEN(NF,FILE=bidule,FORM='UNFORMATTED')
    Puis régulièrement, ie à chaque mise à jour du lot de variables d'intérêt, ces variables sont placées dans un tableau (appelons le TRS) et on écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          WRITE(NF)(TRS(i),i=1,NVAR)
    (avec NVAR=25, et TRS déclaré de longueur NVAR).

    Pour compléter, et si ça peut lever des ambiguïtés (et pour avoir eu à manipuler ces fichiers dans d'autres programmes (ouverture sous Matlab)), je sais décrire précisément le résultat : chaque "ligne" écrit exactement (NVAR+1)*8 octets dans le fichier, comme suit :

    4 octets d'en-tête (dans lequel est inscrit le nombre NVAR=25)
    NVAR*8 octets de valeurs (NVAR variables en double précision)
    4 octets de trailer (dans lequel est inscrit le nombre NVAR=25)

    La structure exacte du fichier résultant est donc :

    4 octets d'en-tête
    NVAR*8 octets (NVAR variables en double précision)
    4 octets de trailer
    4 octets d'en-tête
    NVAR*8octets
    4 octets de trailer
    etc...

    (Précision supplémentaire : à la relecture de ces fichiers, le nombre de "lignes" écrites n'est pas connu (car varie d'un fichier à l'autre), mais en pratique, il est facile à trouver si l'on dispose d'une instruction pour renvoyer la taille en octets du fichier.)

    Est-ce que cela te permet d'y voir plus clair ?

  6. #6
    Membre régulier Avatar de moomba
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 134
    Points : 104
    Points
    104
    Par défaut
    Oui merci. Ca marche de mon côté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    program toto
     
    implicit none
     
    INTEGER :: NF, NVAR, i
    REAL(8), dimension(1:10) :: TRS,DRS
     
    NVAR=7
     
    TRS(:) = 12.0d0
    DRS(:) = 77.0d0
     
    OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
     
          WRITE(NF)(TRS(i),i=1,NVAR)
     
    CLOSE(NF)
     
    OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
     
          READ(NF) DRS(1:NVAR)
     
    CLOSE(NF)
     
    print *,TRS
    print *,DRS
     
    end program
    Puis je compile et je lance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    :~/Desktop$ gfortran Toto.f90
    :~/Desktop$ ./a.out 
       12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000     
       12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        12.000000000000000        77.000000000000000        77.000000000000000        77.000000000000000     
    :~/Desktop$
    Étonnant que tu ne puisses relire le fichier en brut. En fait, le (TRS(i),i=1,NVAR) équivaut au TRS(1:NVAR) en terme de rendu final (je n'ai aucune idée de l'incidence en terme de perfs, mais le second ne peut être qu'égal ou mieux). Peut tu tester de cette façon ?

    On verra ensuite pour le réseau. Note tout de même, astuce de vieux combattant : tu peut fortement gagner en perfs en utilisant des routines C pour l'écriture. Le gain est de 15-30% selon les cas.

  7. #7
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Ton exemple marche parfaitement chez moi aussi, mais je ne suis pas surpris : une seule ligne est écrite, puis relue telle quelle vers le DRS.

    Est-ce que ça marche chez toi avec le programme suivant (je vais essayer chez moi aussi) ? Car ma situation est plutôt celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    program toto
     
    implicit none
     
    INTEGER :: NF, NVAR, NITER, i, j
    REAL(8), dimension(1:10) :: TRS,DRS1,DRS2,DRS3,DRS4,DRS5
     
    NVAR=5
    NITER=3
     
    DRS1(:) = 17.0d0
    DRS2(:) = 27.0d0
    DRS3(:) = 37.0d0
    DRS4(:) = 47.0d0
    DRS5(:) = 57.0d0
     
    OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
     
    do j=1,NITER
      TRS(:) = j*12.0d0
      WRITE(NF)(TRS(i),i=1,NVAR)
    enddo
     
    CLOSE(NF)
     
    OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
     
    READ(NF)DRS1(1:NITER),DRS2(1:NITER),DRS3(1:NITER),DRS4(1:NITER),DRS5(1:NITER)
     
    CLOSE(NF)
     
    print *,DRS1
    print *,DRS2
    print *,DRS3
    print *,DRS4
    print *,DRS5
     
    end program
    Sachant donc pour bien être clair que je ne peux pas m'affranchir de la boucle sur j (la réalité du programme est que les valeurs de TRS changent avec le temps, et que ces valeurs sont régulièrement écrites, d'où le write multiple).

    En gros à un instant donné, TRS contient les valeurs des variables scalaires a,b,c, etc, à l'instant courant.
    Au prochain passage, ces variables scalaires a,b,c,etc auront changé (ou pas), TRS sera mis à jour avec ces valeurs à jour, et écriture du jeu à jour.
    Do'ù la structure physique décrite dans mon message précédent.

    C'est un tel fichier que je souhaite récupérer en un seul READ.

    (ensuite, après récupération, il me faudra être capable de reconstituer des tableaux ta,tb,tc,etc qui contiennent chacun les valeurs au cours du temps de la variable correspondante)

    Réussis-tu, en un unique READ, à récupérer les valeurs du fichier ainsi créé ?

    Edit : après essai, comme prévu, l'exemple codé ici me renvoie comme auparavant :

    Fortran runtime error: I/O past end of record on unformatted file
    à la ligne correspondant au READ.

    On verra ensuite pour le réseau. Note tout de même, astuce de vieux combattant : tu peut fortement gagner en perfs en utilisant des routines C pour l'écriture. Le gain est de 15-30% selon les cas.
    Le temps d'écriture lui-même n'est pas un souci : ce n'est pas moi qui écris ces fichiers, c'est un autre programme qui a été lancé une fois x jours auparavant, par quelqu'un d'autre (mais même machine, pas de souci de ce côté, comme déjà précisé ).

  8. #8
    Membre régulier Avatar de moomba
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 134
    Points : 104
    Points
    104
    Par défaut
    Le programme ne peut pas marcher.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    do j=1,NITER
      TRS(:) = j*12.0d0
      WRITE(NF)(TRS(i),i=1,NVAR)
    enddo
    Écrit NITER lignes, chaque ligne possédant NVAR valeurs.

    Lire de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    READ(NF)DRS1(1:NITER),DRS2(1:NITER),DRS3(1:NITER),DRS4(1:NITER),DRS5(1:NITER)
    Équivaut à lire une seul ligne. Impossible à ma connaissance de lire tout en un seul read donc. Le mieux est de lire par blocs les morceaux de NVAR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    READ(NF)DRS1(1:NVAR)
    READ(NF)DRS2(1:NVAR)
    READ(NF)DRS3(1:NVAR)
    READ(NF)DRS4(1:NVAR)
    READ(NF)DRS5(1:NVAR)
    Je ne vois pas d'autres solutions

  9. #9
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par moomba Voir le message
    Écrit NITER lignes, chaque ligne possédant NVAR valeurs.
    Oui, tout à fait.

    Citation Envoyé par moomba Voir le message
    Le mieux est de lire par blocs les morceaux de NVAR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    READ(NF)DRS1(1:NVAR)
    READ(NF)DRS2(1:NVAR)
    READ(NF)DRS3(1:NVAR)
    READ(NF)DRS4(1:NVAR)
    READ(NF)DRS5(1:NVAR)
    Cette implémentation ne produit pas tout à fait ce dont j'ai besoin au niveau du regroupement des valeurs (pour avoir le bon résultat, c'est une boucle sur j exécutant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    READ(NF)DRS1(j),DRS2(j),DRS3(j),DRS4(j),DRS5(j)
    qui correspondrait), mais sur le principe cela correspond à mon implémentation existante aujourd'hui : elle marche tout à fait, mais je la constate pénalisante en temps de lecture (la raison en étant le 1 READ par ligne, plusieurs milliers de lignes, comme le prouve l'exemple ci-dessous).

    Citation Envoyé par moomba Voir le message
    Je ne vois pas d'autres solutions
    Dans ce cas, je pensais à une méthode alternative :

    1) Lire tout d'un coup, quitte à ne pas avoir le bon format dans le vecteur résultat, par exemple (ce n'est qu'un exemple) (ici pour un fichier de 4927 lignes et vingt-cinq variables, donc 26*8 octets écris par ligne)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    integer*8 ibin(4927*26)
    OPEN(KF,FILE='fichier',FORM='UNFORMATTED',RECL=4927*26*8)
    READ(KF,REC=1) ibin
    Ce qui "marche" au sens ne plante pas, et est cette fois-ci beaucoup plus rapide (par comparaison en temps écoulé avec l'autre méthode), et je pense place bien en mémoire l'intégralité du fichier.

    (ici j'ai pris un vecteur d'entiers mais ce n'est qu'un exemple, l'important est qu'il fasse au total le bon nombre d'octets)

    2) Par contre, bien sûr le ibin n'est pas exploitable en l'état, et il faut faire une manip sur les octets ou l'adressage pour reconstituer les bonnes valeurs à partir de vecteur obtenu. Ca par contre, je ne sais pas faire, mais connaissant l'agencement des données dans le fichier, et donc également dans le vecteur résultat (que je rappelle ci-dessous), j'imagine que c'est possible ?

    4 octets d'en-tête
    8 octets à placer dans DRS1(1)
    8 octets à placer dans DRS2(1)
    ...
    8 octets à placer dans DRS25(1)
    4 octets de trailer
    4 octets d'en-tête
    8 octets à placer dans DRS1(2)
    8 octets à placer dans DRS2(2)
    ...
    8 octets à placer dans DRS25(2)
    4 octets de trailer

    etc... jusque

    4 octets d'en-tête
    8 octets à placer dans DRS1(4927)
    8 octets à placer dans DRS2(4927)
    ...
    8 octets à placer dans DRS25(4927)
    4 octets de trailer

  10. #10
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    J'ai exhibé une solution qui marche, sur le modèle précédent (récup en un coup, au prix d'un réadressage manuel nécessaire ensuite).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
          program toto
     
          implicit none
     
          INTEGER :: NF, NVAR, NLIGNES,i,j,NOCT,kl,io
          PARAMETER(NVAR=5,NLIGNES=7)
          REAL(8), dimension(1:NVAR) :: TRS
          REAL(4), dimension(2*NLIGNES*(NVAR+1)) :: rbin
          REAL(8), dimension(1:(nlignes*nvar)) :: tabout
     
    c     Ecriture ligne à ligne dans le fichier (méthode imposée)
          OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
          do j=1,NLIGNES
            TRS(:) = j*10.0d0+(/1.0d0,2.0d0,3.0d0,4.0d0,5.0d0/)
            WRITE(NF)(TRS(i),i=1,NVAR)
          enddo
          CLOSE(NF)
     
    c     On lit tout le fichier "d'un coup" dans le tableau rbin
    c     (précédemment déclaré à pile la bonne longueur)   
          NOCT=NLIGNES*(NVAR+1)*8
          OPEN(NF,FILE="bidule",FORM='UNFORMATTED',RECL=NOCT,
         &            STATUS='OLD',access='direct')
          READ(NF,REC=1) rbin
          CLOSE(NF)
     
    c     On va enlever les octets d'en-tête de trailer de chaque ligne
    c     Noter que tabout est déclaré en double précision
    c     (comme les valeurs initiales) dans le code principal
          call remht(rbin,nlignes,nvar,tabout)
     
          do kl=1,nlignes
            io=(kl-1)*nvar
            print*,tabout(io+1:io+nvar)
          enddo
     
          end
    Avec remht la subroutine suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
          subroutine remht(tabin,nlignes,nvar,tabout)
          REAL(4), dimension(1:2*nlignes*(nvar+1)) :: tabin
          REAL(4), dimension(1:2*nlignes*nvar) :: tabout
     
    c     Ici on doit travailler par paquets de 4 octets (à cause des en-têtes et trailers qui ont cette taille)
    c     d'où la déclaration en REAL(4)
    c     On a en revanche déclaré 2 fois plus de variables pour compenser
    c     (ainsi les tableaux font bien la bonne taille en octets)
          do kl=1,nlignes
            ii=1+(kl-1)*2*(nvar+1)
            io=(kl-1)*2*nvar
            tabout(io+1:io+2*nvar)=tabin(ii+1:ii+2*nvar)
          enddo
     
          return
          end
    J'ai bien obtenu le print attendu, et la lecture est plus rapide que l'implémentation "standard" avec boucle sur les READ.

    En revanche la façon dont je m'y suis pris est relativement peu portable car je suis forcé de déclarer tabout en simple précision d'un côté et en double de l'autre (pour pouvoir manipuler 4 octets par 4 octets dans remht, puis pour bien être interprété 8 octets par 8 octets comme il faut). Ca passe sans souci sous gfortran, mais ifort refuse de compiler (erreur, pas juste un warning...).

    En revanche, tout se passe bien avec transfer (au stack overflow près du aux réglages par défaut de ifort sur ce point, qu'il m'a fallu changer).

  11. #11
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Un troisième message mais cela me semble mieux pour la clarté...

    En fait une solution encore plus simple au dernier problème d'allocation est tout simplement d'utiliser un EQUIVALENCE. Ainsi pas de copie à réaliser, et on peut corriger sans rien faire a) le décalage initial de 4 octets voulu b) le passage à 8 octets.

    Par contre à chaque fin de ligne reste une valeur supplémentaire (correspondant au trailer+header) qu'il suffit d'ignorer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
          program toto
     
          implicit none
     
          INTEGER :: NF, NVAR, NLIGNES,i,j,NOCT,kl,io
          PARAMETER(NVAR=5,NLIGNES=7)
          REAL*8 TRS(NVAR)
          REAL*4 rbin(2*NLIGNES*(NVAR+1))
          REAL*8 tabout(nlignes*(nvar+1))
          EQUIVALENCE(rbin(2),tabout(1))
     
    c     Ecriture ligne à ligne dans le fichier (méthode imposée)
          OPEN(NF,FILE="bidule",FORM='UNFORMATTED')
          do j=1,NLIGNES
            TRS(:) = j*10.0d0+(/1.0d0,2.0d0,3.0d0,4.0d0,5.0d0/)
            WRITE(NF)(TRS(i),i=1,NVAR)
          enddo
          CLOSE(NF)
     
    c     On lit tout le fichier "d'un coup" dans le tableau rbin
    c     (précédemment déclaré à pile la bonne longueur)   
          NOCT=NLIGNES*(NVAR+1)*8
          OPEN(NF,FILE="bidule",FORM='UNFORMATTED',RECL=NOCT,
         &            STATUS='OLD',access='direct')
          READ(NF,REC=1) rbin
          CLOSE(NF)
     
          do kl=1,nlignes
            io=(kl-1)*(nvar+1)
            print*,tabout(io+1:io+nvar)
          enddo
     
          end

  12. #12
    Membre régulier Avatar de moomba
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 134
    Points : 104
    Points
    104
    Par défaut
    En retard

    Effectivement, tout charger en mémoire (si la taille du fichier reste raisonnable) est une solution au problème. J'aime beaucoup le tour de force avec Equivalence (j'avoue que je ne connaissais pas cette instruction). L'avantage est que tu restes dans les normes sans prendre le risque de faire du 'jardinage' (jargon pour "piocher dans la mauvaise zone mémoire").

    Belle auto-résolution !

    (et du coup, c'est moi qui apprend un truc )

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

Discussions similaires

  1. Accès à des fichiers binaires en Python
    Par dapounet dans le forum Général Python
    Réponses: 5
    Dernier message: 01/04/2009, 22h08
  2. Réponses: 5
    Dernier message: 02/10/2006, 22h54
  3. Temps d'acces aux fichiers liés...
    Par PAUL87 dans le forum Access
    Réponses: 2
    Dernier message: 08/12/2005, 15h08
  4. Acces fichier binaire C++
    Par Glosialabolas dans le forum C++
    Réponses: 4
    Dernier message: 20/10/2005, 17h42
  5. Temps d'accès à des données dans un fichier
    Par TONIAPEL dans le forum Assembleur
    Réponses: 5
    Dernier message: 28/09/2003, 15h21

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