Vid utmatning på papper är det naturligtvis viktigt att det hela är läsbart, därför bör formaterad eller liststyrd utmatning användas. Vid mellanlagring bör man i stället se till effektiviteten och därför använda oformaterad utmatning, vilket dels drar litet datorresurser och dels ger en kompakt lagring. Vid behov av att läsa mellanresultat "med ögonen" kan man enkelt skriva ett program som läser den oformaterade filen och skriver den formaterat antingen direkt på skärmen eller på en annan fil för senare utmatning på papper.
Anm. Många implementationer klarar högre nummer än 99.
För att kunna använda filer måste de först öppnas och sedan stängas. Flera Fortransystem (till exempel Sun och DEC Fortran 77 samt Cray under både Fortran 77 och 90) öppnar dock vid behov automatiskt filer som svarar mot Fortrans nummer, till exempel en fil fort.7 vid utmatning på logisk enhet 7, samt stänger alla öppna filer vid normalt programslut. Andra system (till exempel NAG Fortran 90 på Sun och DEC) kräver att filen har öppnats explicit innan den kan användas, de ger annars en felutskrift när filen behövs.
Om man skall skapa en fil för vanlig utmatning är det mycket enkelt, efter att ha valt ett enhetsnummer och ett filnamn använder man kommandot OPEN och får tillgång till att skriva på filen. När man är klar bör man stänga filen med kommandot CLOSE.
NOUT = 20
OPEN(NOUT,FILE='UTFIL.TXT')
WRITE(NOUT,*) lista1
WRITE(NOUT,10) lista2
10 FORMAT( ) ! Här måste en formatspecifikation finnas.
CLOSE(NOUT)
Man kan nu läsa filen. Även nu måste man först öppna
den med kommandot
OPEN och man bör stänga filen med kommandot CLOSE.
Man behöver inte använda
samma enhetsnummer, men man måste använda samma filnamn.
NIN = 30
OPEN(NIN,FILE='UTFIL.TXT')
READ(NIN,*) lista1
READ(NIN,10) lista2
10 FORMAT( ) ! Här måste en formatspecifikation finnas.
! Den måste passa med hur filen skrivits.
CLOSE(NIN)
Vanliga filer kan antingen vara formaterade eller oformaterade, normalt är formaterade.
Kommandot OPEN
När man skall skapa en fil väljer man ett enhetsnummer och ett filnamn, och med kommandot
OPEN öppnar man filen. Detta kommando kan ges ett stort antal attribut
UNIT, FILE, STATUS,
ACCESS, FORM, RECL, BLANK, ERR, IOSTAT, ACTION, POSITION, DELIM och PAD.
NOUT = 20
OPEN(NOUT, FILE='UTFIL.TXT', STATUS='NEW', &
ACCESS='DIRECT', FORM='FORMATTED')
När man är klar med användningen av en fil bör man stänga filen med
kommandot CLOSE. Detta kommando kan ges ett mindre antal attribut, nämligen
UNIT, STATUS, ERR och IOSTAT.
CLOSE(NOUT, STATUS = 'DELETE')
INQUIRE(UNIT = nummer, lista)
eller
INQUIRE(FILE = filnamn, lista)
I lista anges exempelvis EXIST = logisk_variabel, varvid
den logiska variabeln får värdet sant om respektive fil finns,
annars får den värdet falsk. Här följer övriga
möjliga parametrar:
INQUIRE(IOLENGTH = laengd) lista
Här är lista en utmatningslista, till exempel A(1:N).
Man får då i laengd reda på längden i
systemberoende enheter för motsvarande oformaterade utmatning.
Detta kan vara värdefullt i samband med postlängden RECL i
direkt-accessfiler.
Direktaccess-filer användes exempelvis på databaser, som ofta består av ett visst antal fixa poster. Ett bra exempel är en telefonkatalog med ett visst antal tecken för efternamn, förnamn, titel, adress, postnummer, adressort och telefonnummer. Numera är dock de flesta databaser relationella, men om man vill koppla en databas till ett Fortranprogram kan man behöva exportera databasen till en direktaccess-fil i Fortran.
Notera att både vanliga filer (sekventiella) och direktaccess-filer oftast lagras på skivminnen, vilka ofta kallas för direkt access minnen, men då användes direkt access i betydelsen on line.
Direktaccess-filer kan antingen vara formaterade eller oformaterade, normalt är oformaterade.
Vid användning av direktaccess-filer tillkommer några attribut till READ och WRITE-satserna, jämför avsnitt 7.7.
Jag använde direktaccess-filer mycket under min tid på Försvarets Forskningsanstalt. Under varje postnummer (REC=nr) lagrade jag rutnätet och alla tillhörande storheter vid en viss tidpunkt för lösningen av en hyperbolisk differentialekvation. Med ett program kunde jag sedan välja ut lämplig tidpunkt (postnummer) och plotta ut önskade storheter vid denna tidpunkt. Med att annat program kunde jag plotta valda storheter som funktion av tiden. Direktaccessfilen kunde även användas för omstart (fortsättning av föregående körning).
Jag ger här ett mycket enkelt exempel på användning av direktaccess-filer, nämligen en databas med telefonnummer över personalen vid Nationellt Superdatorcentrum.
Det första programmet skapar databasen, vilken jag valt vara formaterad och med längden 120 tecken för varje post. Inmatningen av data har jag gjort på enklast möjliga sätt, varefter jag skriver ut den i omvänd ordning. De första 50 positionerna i fältet på direktaccess-filen placeras högerjusterade i X, varför jag vänsterjusterar med ADJUSTL före utmatningen.
PROGRAM DIREKT_ACCESS
IMPLICIT NONE
INTEGER, PARAMETER :: NDIR = 20
INTEGER :: NR
CHARACTER*50 :: X
OPEN(NDIR, FILE='direkt.acc', STATUS='UNKNOWN', &
ACCESS='DIRECT', FORM='FORMATTED', RECL=120)
WRITE(NDIR,10,REC=1) "Bo Einarsson;013-281432"
WRITE(NDIR,10,REC=2) "Bo Sjögren;013-282625"
WRITE(NDIR,10,REC=3) "Mats S Andersson;013-282568"
WRITE(NDIR,10,REC=4) "Ulla Bjuhr-Jönsson;013-282618"
WRITE(NDIR,10,REC=5) "Larsgunnar Nilsson;013-281107"
DO NR = 5, 1, -1
READ(NDIR,10,REC=NR) X
WRITE(*,*) ADJUSTL(X)
END DO
CLOSE(NDIR)
STOP
10 FORMAT(A50)
END PROGRAM DIREKT_ACCESS
Det andra programmet använder databasen, man ger önskat postnummer och får ut
önskad individ. Notera att man inte behöver läsa in hela databasen, utan bara
den post som man är intresserad av.
PROGRAM LAES_DIREKT_ACCESS
IMPLICIT NONE
INTEGER, PARAMETER :: NDIR = 20
INTEGER :: NR
CHARACTER*50 :: X
OPEN(NDIR, FILE='direkt.acc', STATUS='OLD', &
ACCESS='DIRECT', FORM='FORMATTED', RECL=120)
DO
WRITE(*,'(A)',ADVANCE='NO') ' Ge nr = '
READ(*,*) NR
IF (NR < 1 ) EXIT
READ(NDIR,10,REC=NR) X
WRITE(*,*) ADJUSTL(X)
END DO
CLOSE(NDIR)
STOP
10 FORMAT(A50)
END PROGRAM LAES_DIREKT_ACCESS
Begreppet ADVANCE behandlas i avsnitt 16.4.
Ett exempel ges nedan på detta (något krångliga) förfarande, kört både på den gamla DEC-20 under operativsystemet TOPS-20 och på en modern UNIX-maskin. Vi skapar här den interna filen genom att deklarera KORT som en textsträng med 80 tecken. Vanlig inläsning utnyttjande textformat sker till denna interna fil i sats nummer 15 nedan, vanlig utskrift av den sker i sats 22, medan den interna filen återanvändes för inläsning i satserna 28 och 50, utnyttjande heltals respektive flyttalsformat.
PROGRAM INTERN
C DETTA PROGRAM DEMONSTRERAR ANVÄNDNINGEN AV INTERNA
C FILER. NOTERA ATT IBLAND BETRAKTAS BLANKA SOM NOLLOR,
C DVS PÅ TOPS-20 ANVÄNDES BZ. VID VANLIG
C HELTALSINMATNING UNDER TOPS-20 GÄLLDE DÄREMOT BN.
C UNDER UNIX GÄLLER BN.
CHARACTER KORT*80
INTEGER HELTAL
REAL FLYTAL
10 WRITE(6,11)
11 FORMAT(' IN: ')
15 READ(5,20,END=90) KORT
20 FORMAT(A80)
22 WRITE(6,25) KORT
25 FORMAT(' UT: ',A80)
28 READ(KORT,30,ERR=50) HELTAL
30 FORMAT(I5)
WRITE(6,40) HELTAL
40 FORMAT(' HELTAL = ',I5)
GOTO 10
50 READ(KORT,60,ERR=80) FLYTAL
60 FORMAT(F20.5)
WRITE(6,70) FLYTAL
70 FORMAT(' FLYTTAL = ',F15.8)
GOTO 10
80 CONTINUE
GOTO 10
90 STOP
END
Programmet ovan läser in en post (rad, hålkort med 80 tecken) och skriver ut den oförändrad.
Därefter kollar programmet om det står ett heltal i de första fem positionerna,
i så fall skrivs heltalet ut och programmet begär ny post. Om programmet ej funnit
heltal kollar det i stället om det är ett flyttal i de första 20 positionerna,
skriver ut det och begär nästa post. Man slutar genom att ge sluttecknet Kontroll-z.
Ovanstående princip kan användas om man inte vet exakt vilken typ av data som kommer.
Körning av detta program gav på DEC-20 under TOPS-20 respektive på Sun SPARC under Sun OS 4.1.2.
DEC Sun (vid skillnad)
@EX INTERN f77 intern.f
FORTRAN: INTERN intern.f
INTERN MAIN intern:
LINK: Loading a.out
LNKXCT INTERN execution
IN:
ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖÉÜ
UT: ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖÉÜ
IN:
12345
UT: 12345
HELTAL = 12345
IN:
1
UT: 1
HELTAL = 10000 HELTAL = 1
IN:
1 1 1
UT: 1 1 1
HELTAL = 10101 HELTAL = 111
IN:
12.56
UT: 12.56
FLYTTAL = 12.55999994 FLYTTAL = 12.56000042
IN:
9.1
UT: 9.1
FLYTTAL = 9.10000002 FLYTTAL = 9.10000038
IN:
9.1
UT: 9.1
FLYTTAL = 9.10000002 FLYTTAL = 9.10000038
IN:
kontroll-Z
Suspended