Programmeren in COBOL/Bestandsorganisatie/Sequentiële bestanden

Uit Wikibooks
Naar navigatie springen Naar zoeken springen

Programmeren in COBOL

Inhoudsopgave

  1. Sequentiële bestanden Zeer goed ontwikkeld. Revisiedatum: 21 oktober 2007 (Oef Redelijk ontwikkeld. Revisiedatum: 21 oktober 2007 )
  2. Relatieve bestanden zonder hash Zeer goed ontwikkeld. Revisiedatum: 20 november 2007 (Oef Nog vrijwel niets. Revisiedatum: 20 november 2007 )
  3. Relatieve bestanden met hash Goed ontwikkeld. Revisiedatum: 21 oktober 2007 (Oef Nog vrijwel niets. Revisiedatum: 23 november 2007 )
  4. Index-sequentiële bestanden Nog vrijwel niets. Revisiedatum: 21 oktober 2007 (Oef Nog vrijwel niets. Revisiedatum: 20 november 2007 )





Dit is een hoofdstuk van Programmeren in COBOL. Hier zul je leren hoe je sequentiële bestanden kunt lezen.

Voorbeeld van een sequentieel bestand[bewerken]

Een sequentieel bestand is een bestand waar iedere lijn een record vormt. Een record zal gegevens opslaan voor bijvoorbeeld één persoon. Een sequentieel bestand kan verschillende datatypes (of extensies) hebben. Wij zullen .txt gebruiken. Maar dat kan natuurlijk ook .dat of .in of iets anders zijn.

COBOL-code: Sequentieel bestand

Peeters             Jan            Kerkplein 8               ZAVENTEM      M
Jansen              Peter          Stationstraat 124         KAMPENHOUT    M

In dit sequentieel bestand worden de naam, adres en geslacht van een persoon opgeslagen.

Sequentiële bestanden lezen[bewerken]

Next.svg  Zie ook READ voor meer informatie.

We gaan een klein programma schrijven dat de gegevens inleest en alleen de achternaam, voornaam en geslacht op het scherm toont.

COBOL-code: Sequentieel bestand lezen

       IDENTIFICATION DIVISION.
       PROGRAM-ID. seqbestanlezen.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam  PIC X(20).
        02 voornaam    PIC X(15).
        02 adres       PIC X(26).
        02 plaats      PIC X(14).
        02 geslacht    PIC X.

       WORKING-STORAGE SECTION.
       77       PIC X  VALUE "n".
         88 eof        VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT invoer
           READ invoer AT END SET eof TO TRUE END-READ
           PERFORM lees UNTIL eof
           CLOSE invoer
           STOP RUN.

       LEES.
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .
Jan             Peeters              M
Peter           Jansen               M

Nu gaan we dat een beetje uitleggen.

COBOL-code: Sequentieel bestand lezen

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

Als er gewerkt wordt met bestanden wordt dit stukje toegevoegd. Het bestand invoer.txt wordt gekoppeld met invoer wat belangrijk is in de DATA DIVISION. LINE SEQUENTIAL geeft aan dat het een sequentieel bestand is.

COBOL-code: Sequentieel bestand lezen

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam PIC X(20).
        02 voornaam PIC X(15).
        02 geslacht PIC X.

In de DATA DIVISION komt er de FILE SECTION bij. Er wordt gebruik gemaakt van groepsvelden om de gegevens in op te slaan. In dit geval is dat persoon.

COBOL-code: Sequentieel bestand lezen

           OPEN INPUT invoer
           READ invoer AT END SET eof TO TRUE END-READ

In de programmacode moet het bestand eerst worden geopend. Dit doe je met OPEN INPUT, gevolgd door de naam van het bestand. Daarna doe je een READ. De boolean eof is nodig voor een lus. Als je op het einde van een bestand zit, wordt deze op TRUE gezet. Daardoor kan een lus weten wanneer je op het einde zit. Een READ leest slechts één record in één keer. Alle gegevens worden dan in het groepsveld persoon gezet. Wanneer je daarna nog een READ doet, gaat hij naar het volgende record en gaan de gegevens van het vorige verloren.

COBOL-code: Sequentieel bestand lezen

           PERFORM lees UNTIL eof

Dit is een verwijzing naar een deelprogramma maar ook een lus. Dit zal het deelprogramma blijven uitvoeren tot het aan het einde is van het bestand. Hiervoor wordt de variabele eof gebruikt, als die op true gezet wordt, eindigt de lus.

COBOL-code: Sequentieel bestand lezen

       LEES.
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .

Dit is het deelprogramma. Eerst toont het op het scherm wat het de vorige keer uit het bestand heeft gelezen. Daarna leest het een nieuwe record.

COBOL-code: Sequentieel bestand lezen

           CLOSE invoer

Nadat je gedaan hebt met het lezen van het bestand, moet je het bestand terug sluiten met CLOSE.

Sequentiële bestanden schrijven[bewerken]

Next.svg  Zie ook WRITE voor meer informatie.

Een bestand schrijven volgt natuurlijk het omgekeerde principe van een bestand lezen. Je verwerkt eerst de gegevens je plaatst die in het groepsveld van de uitvoer en vervolgens schrijf je het bestand. We zullen in dit voorbeeld een bestand openen en daarna lezen wat er in zit om dat te verwerken en uit te schrijven. Je moet natuurlijk niet een bestand lezen; je kan gewoon de gegevens inlezen via een ACCEPT, maar dat neemt tijd in beslag. We gebruiken in dit voorbeeld hetzelfde sequentieel bestand om te lezen als in het vorige.

COBOL-code: Sequentieel bestand schrijven

       IDENTIFICATION DIVISION.
       PROGRAM-ID. seqbestanschrijven.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT invoer ASSIGN TO "invoer.txt"
           LINE SEQUENTIAL.

           SELECT uitvoer ASSIGN to "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD invoer.
       01 persoon.
        02 achternaam PIC X(20).
        02 voornaam   PIC X(15).
        02 geslacht   PIC X.


       FD uitvoer.
       01 regel.
        02 uitvn PIC X(15).
        02       PIC X.
        02 uitan PIC X(20).
        02       PIC X.
        02 uitge PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN INPUT invoer
           OPEN OUTPUT uitvoer
           READ invoer AT END SET eof TO TRUE END-READ
           PERFORM lees UNTIL eof

           CLOSE invoer
           CLOSE uitvoer
           STOP RUN.

       LEES.
           MOVE achternaam TO uitan
           MOVE voornaam TO uitvn
           MOVE geslacht TO uitge
           WRITE regel END-WRITE
           DISPLAY voornaam " " achternaam " " geslacht
           READ invoer AT END SET eof TO TRUE END-READ
           .

Een uitvoer-bestand wordt op dezelfde manier gekoppeld met een groepsveld en ook op dezelfde manier gesloten. Het bestand openen gebeurt op een andere manier "OPEN OUTPUT uitvoer". In COBOL wordt namelijk een bestand gelezen, terwijl een record geschreven wordt.

COBOL-code: Sequentieel bestand schrijven

           MOVE achternaam TO uitan
           MOVE voornaam TO uitvn
           MOVE geslacht TO uitge
           WRITE regel END-WRITE

Het enige waar er moet op gelet worden, is het overzetten van de variabelen van het éne groepsveld naar het andere en ook de WRITE-commando gevolgd door de groepsveld van de uitvoer en de END-WRITE. Hieronder bevindt zicht het resultaat van dit programma.

Jan             Peeters              M
Peter           Jansen               M

Record achteraan toevoegen[bewerken]

Telkens we OPEN OUTPUT doen en we schrijven daar iets in wordt er eigenlijk een nieuw bestand opgeslagen m.a.w. als er al een bestand bestond met dezelfde naam gaan de gegevens in dat bestand verloren en wordt het vervangen door andere gegevens. Daardoor kun je geen record toevoegen met OPEN OUTPUT hievoor moet je OPEN EXTEND gebruiken. OPEN EXTEND betekent dat je automatisch vanachter gegevens kunt toevoegen. In dit volgende programma gaat de gebruiker gegevens van een persoon opgeven en die worden achteraan toegevoegd.

COBOL-code: Record achteraan toevoegen.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. RecordToevoegen.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT uitvoer ASSIGN to "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD uitvoer.
       01 regel.
        02 uitvn PIC X(15).
        02       PIC X.
        02 uitan PIC X(20).
        02       PIC X.
        02 uitge PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".

       PROCEDURE DIVISION.
       HOOFD.
           OPEN EXTEND uitvoer
           DISPLAY "Geef de voornaam:"
           ACCEPT uitvn NO BEEP
           DISPLAY "Geef de achternaam:"
           ACCEPT uitan NO BEEP
           DISPLAY "Geef het geslacht:"
           ACCEPT uitge NO BEEP
           WRITE regel END-WRITE
           CLOSE uitvoer
           STOP RUN.

Niet zo moeilijk, dus gewoon in de plaats van OPEN OUTPUT moet je OPEN EXTEND gebruiken.

Record herschrijven[bewerken]

Next.svg  Zie ook REWRITE voor meer informatie.

Het is mogelijk bij een sequentieel bestand een record te herschrijven. Dit is echter onpraktisch. Als je één bepaald record wilt aanpassen heb je twee keuzes: ofwel ga je alle records één voor één af tot je de juiste record hebt gevonden, ofwel schrijf je een programma dat zelf alle records afgaat en vind wat je zoekt. Daardoor zijn sequentiële bestanden niet de goede oplossing als je weet dat je uw records vaak zult moeten aanpassen. Hiervoor zijn betere bestandsorganisaties die later nog aan bod komen. In het volgende programma krijgt de gebruiker ieder record te zien en wordt hem gevraagd of hij ze wilt herschrijven.

COBOL-code: Record herschrijven.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. recordHerschrijven.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT bestand ASSIGN TO "uitvoer.txt"
           LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD bestand.
       01 regel.
        02 voornaam   PIC X(15).
        02            PIC X.
        02 achternaam PIC X(20).
        02            PIC X.
        02 geslacht   PIC X.

       WORKING-STORAGE SECTION.
       77        PIC X  VALUE "n".
         88 eof         VALUE "j".
       77 invoer PIC X.

       PROCEDURE DIVISION.
       HOOFD.
           OPEN I-O bestand
           READ bestand AT END SET eof TO TRUE END-READ
           PERFORM herschrijf UNTIL eof
           CLOSE bestand
           STOP RUN.

       HERSCHRIJF.
           DISPLAY voornaam " " achternaam " " geslacht
           DISPLAY "Wilt u de gegevens van deze persoon aanpassen"
                   "(0=neen)"
           ACCEPT invoer NO BEEP
           IF invoer = 0
             THEN DISPLAY "Geen gegevens aangepast"
             ELSE 
              DISPLAY "Geef de voornaam:"
              ACCEPT voornaam NO BEEP
              DISPLAY "Geef de achternaam:"
              ACCEPT achternaam NO BEEP
              DISPLAY "Geef het geslacht:"
              ACCEPT geslacht NO BEEP
              REWRITE regel END-REWRITE
           END-IF
           READ bestand AT END SET eof TO TRUE END-READ
           .

Een record herschrijven op zich is niet zo moeilijk. Er zijn twee dingen waar je wel voor moet opletten. I-O of INPUT-OUTPUT dit betekent dat een bestand zal worden gezien als invoer en als uitvoer. Dit komt omdat je eerst de records moet lezen voor je ze kan herschrijven. Je moet dus altijd I-O of INPUT-OUTPUT gebruiken als je iets wilt herschrijven. Voor je iets kunt herschrijven moet je eerst iets lezen met de READ en vervolgens herschrijf je het met de REWRITE. REWRITE werkt hetzelde als WRITE.

Record verwijderen[bewerken]

Je kunt bij sequentiële bestanden geen records verwijderen. Wat je echter wel kunt doen is de record herschrijven en opvullen met spaties. Je kunt dan een beveiliging inbouwen zodat wanneer de record wordt gelezen die bijvoorbeeld wordt overgeslagen. Je hoeft natuurlijk je record niet opvullen met spaties dit mag natuurlijk ook iets anders zijn of in ieder geval één of ander kenmerk zodat je programma weet dat deze record moet worden overgeslagen.

Informatie afkomstig van http://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.