Failide kasutamine

FAIL üldmõistena on kettale salvestatud ühtne andmekogum. Mingi tekstidokument, tabel, graafiline kujutis jms. moodustavad kettale salvestatuna igaüks mingi faili. Faili iseloomustavad nimi, laiend e.tunnus, suurus e. maht (baitides) ja loomise aeg.

Pascali kontekstis räägitakse failide puhul enamasti andmefailidest. Andmefail on mingi programmeerimisülesande puhul kas sisend- või väljundandmete hoiukoht. Näiteks võib Pascal-programm lugeda andmeid peale klaviatuuri (tavaline readln-lause) ka failist või väljastada saadud tulemused peale kuvari ka mingisse faili. Sisendfaili kasutamine võimaldab käivitada üht programmi samade andmetega palju kordi (ei pea uuesti sisestama - näiteks tabeli puhul suur ajavõit).
Väljundfail garanteerib saadud tulemuste säilimise. 

Süntaks: 

'TYPE' <failitüübi_nimi> '=' 'FILE' 'OF' <tüüp> ';' .
'VAR' <failimuutuja_nimi> ':' <failitüübi_nimi> ';' .
'Assign' '(' <failimuutuja_nimi> ',' <faili_nimi> ')' ';' . 
Lugemiseks avamine toimub järgmise käsuga (operatsiooni õnnestumise eelduseks on faili olemasolu): 
'Reset' '(' <failimuutuja_nimi> ')' ';' . 
Kirjutamiseks avamine toimub järgmise käsuga: 
'Rewrite' '(' <failimuutuja_nimi> ')' ';' .
Näide: 

Type Tekstifail = File Of Char; (* pole vaja TP5.5 *)
Var Sisendfail : Tekstifail; (* TP5.5-l : text *)
... 
Assign(Sisendfail, 'LOEMIND.TXT');
Reset(Sisendfail);

Failist sisestamiseks (lugemiseks) ja faili väljastamiseks (kirjutamiseks) kasutatakse samu lauseid, mida tavaliseks sisestuseks ja väljastuseks. Lisandub vaid faili nimi:

read( < faili nimi >, muutuja );

write( < faili nimi >, muutuja );

N: read(andmed, vanus); ---> failist "andmed" loetakse väärtus ja pannakse muutujasse "vanus".

write(ryhm, nimi); ---> faili "ryhm" kirjutatakse (lisatakse) muutuja "nimi" väärtus.

Analoogiliselt tavaliste muutujate ja massiividega tuleb ka failid deklareerida. Pascalis kasutatakse kaht liiki faile. Esimese liigina vaatleme jadafaile.

Jadafail koosneb ühesugustest andmetest, mis paiknevad failis järjestikku (tihti iga element eraldi real).
Iga faili element aga võib sisaldada mitut väärtust, näiteks võib programmirida

writeln(andmed, nimi,vanus,jalanumber);

väljastada faili "andmed" kolm väärtust ning faili üks element (rida) võib olla näiteks selline:
Albert 20 43 (nimi vanus ja jalanumber)

Pöördtehtena toimub eelmise rea lugemine failist nii:

readln(andmed, nimi, vanus, jalanumber);

Vastavalt muutuja "nimi" saab väärtuseks "Albert", "vanus" - 20 ja "jalanumber" - 43

Jadafaili deklareerimine:
Deklareeritakse programmi var-osas, tüübiks pannakse TEXT.

N: var nimekiri : text;

NB!!! TEXT ei tähenda, et fail peab sisaldama ainult teksti. Ka arvandmeid sisaldavad jadafailid deklareeritakse TEXT-tüübiga.

Lisaks deklareerimisele tuleb kasutatavad failid ka avada. Seda tehakse vastavalt RESET (lugemise või lisamise puhul) või REWRITE (uue faili loomise ja kirjutamise puhul) -lausetega. 
Avamislauses sisaldub kaks failinime - loogiline ja füüsiline failinimi.
Loogiline failinimi on see, mida meie programm kasutab selle faili tähisena (nagu ülaltoodud "nimekiri"). Füüsiline failinimi väljendab kettal asuva reaalse infokogumi nime. Seega näiteks lause

Reset ( nimekiri , ‘nimekiri.dat’ );

avab lugemiseks (s.t. sisendfailina) faili, mis saab programmis nimeks "nimekiri" ja mille tegelik nimi kettal on "nimekiri.dat". Seega avamislause seab omavahel vastavusse loogilise (programmi-) ja füüsilise (ketta-) faili.

Loogiline ja füüsiline nimi võivad ka täiesti erineda. Näiteks:

Rewrite ( andmed, ‘tabel.tab’ );

avab (täpsemalt loob) uue faili, mis salvestatakse kettale nime "tabel.tab" all, kuid millele programmis viidatakse nimega "andmed".

Failide kasutamisel! 
Pärast faili avamist saab faili lugeda ja kirjutada vastavalt sellele, missuguste parameetritega fail avati. Pärast töö lõpetamist tuleb fail sulgeda. Kui fail jätta sulgemata, siis ei pruugi Teie poolt kirjutatud andmed faili jõuda. Failide kasutamise kõigi võimalustega tutvumine ei mahu kahjuks selle kursuse raamidesse ja seda tuleb igalühel õppida läbi oma kogemuste. 

Järgnev näide on faili kasutamise näide reaalses olukorras. Kui soovite seda näidet muutmata kasutada, otsige oma kaustast mõni olemasolev, teksti sisaldav fail ja nimetage ta ümber failiks "Input.txt"

program Failin2ide;

var 
Rida : String[80]; (* määratleme ühe tekstirea muutujaks *)
Sisendfail, Valjundfail : Text; (* failimuutujate määratlused *)
begin
Assign(Sisendfail, 'Input.txt'); (* anname failimuutujatele algväärused *)
Assign(Valjundfail, 'Output.txt');
Reset(Sisendfail); (*  avame failid  *)
Rewrite(Valjundfail);
ReadLn(Sisendfail, Rida); (* loeme failist 'Input.txt' esimese rea *)
WriteLn(Valjundfail, Rida); (* ja kirjutame selle faili 'Output.txt' *)
Close(Valjundfail); (* suleme failid *)
Close(Sisendfail);
end.


Programminäide 10. REPEAT-tsükkel + väljastamine faili.

program Ruutjuur3;
(* Programm küsib kasutaja käest arvu ja väljastab selle ruutjuure. *)
(* Töötatakse seni, kuni kasutaja sisestab arvuks nulli. Kasutatakse *)
(* REPEAT-kordust (järelkontrolliga). *)
(* Tulemused väljastatakse faili juured.dat . *)
var 
arv, juur : real;
juurefail : text;
begin

assign (juurefail, 'juured.dat');

rewrite (juurefail);
arv := 1;
writeln('Töö lõpetamiseks sisesta arvuks 0.');
repeat (* korda.... *)
write('Sisesta arv: ');
readln(arv);
juur := sqrt(arv);
writeln(arv:7:2, ' ruutjuur on ' , juur;7;2); (* kirjutame kuvarile .... *)
writeln(juurefail, arv:7:2, ' ruutjuur on ' , juur:7:2); (* ja faili ka. *)
until arv=0; (* ... kuni arv on 0. Tsükli lõpp *)
writeln('Ongi kõik.');

close(juurefail);
end.

Programminäide 11. Loome faili ja sisestame rühma nimekirja.

program Nimekiri1;
(* Programm sisestab rühma nimekirja. Nimekirja lõppu *)
(* sisestada nime kohale " - " (kriips või miinus) *)
var 
nimi : string;
nimefail : text;
begin
assign (nimefail, ‘nimekiri.dat’);

rewrite (nimefail);
repeat 
write ( ' Sisesta nimi: ' ); 
readln (nimi); (* loetakse nimi .... *)
write(nimefail, nimi); (* ... ja kirjutatakse nimefaili *)
until nimi = ' - ';
writeln('Ongi kõik.');

close(nimefail);
end.


Programminäide 12. Kasutame eelmise programmi faili.

program Nimekiri2;
(* programm väljastab rühma nimekirja *);
var 
nimi : string;
nimefail : text;
begin
assign (nimefail, ‘nimed.dat’);

reset (nimefail);
writeln( ' Rühma MA-11 nimekiri : ' );
writeln( ' ----------------------------------- ' );
while not Eof( ) do (* tee kuni faili lõpuni *)
begin
read(nimefail, nimi);
writeln(nimi);
end;

close(nimefail);
end.


PROOVIGE ISE:

1. Lisage eelmisse näitesse programmiosa, mis kontrollib nimekirja mingi etteantud nime suhtes .Näiteks programm otsib isand Ilumetsa ja ütleb väljastamisel selle nime juurde "sai eksmati."

2. Proovige kombineerida eelmises harjutuses (massiivid) vaadeldud tabeliprogrammile (näide 9) faili sisestamise osa. 

3. Metsafirma palkidearvestus. Eraldi väikese programmiga luua fail, mille igale reale sisestatakse ühe palgi pikkus ning kummagi otsa läbimõõt (oletame, et palk muutub ühtlaselt peenemaks, s.o. on tüvikoonuse kujuga).
Peaprogrammi ülesandeks on lugeda sisendfailist palkide andmed ning leida 
palkide ruumala. Ruumalad tuleb väljastada teise faili, palkide kogu- ruumala aga väljastada ekraanile.


Kodutööde ja arvestusülesannete väljatrükkidel peab olema kommentaaripäis programmi tegevuse eesmärgi ning autori nime ja rühmaga.

N: program Silinder:
(* programm leiab silindri pindala ja ruumala *)
(* Autor: Aadu Kadakas AV-11 *)