Prístup k súborom na disku je dôležitý takmer pre každú bežnú aplikáciu. Ukážme si, ako sa s nimi pracuje v Pascale.
Najprv je potrebné vytvoriť premennú, ktorá bude daný súbor symbolizovať. Táto premenná môže byť typu file
- tzv. netypovaný súbor, file of nejaký_typ
- súbor s určeným typom, text
- textový súbor.
var Subor: Text;
Teraz je treba premennú „zviazať“ s konkrétnym súborom na disku. Slúži na to procedúra Assign
(v Delphi-móde AssignFile
).
Assign(Subor, 'C:\MOJE.TXT');
Premenná subor bude odteraz odkazovať na súbor C:\MOJE.TXT. Ak nemáte prístup do priečnika C:\, radšej zapisujte do aktuálneho adresára - je to priečinok, v ktorom sa práve nachádzate a z ktorého bol program spustený. Stačí úplne vynechať cestu k súboru:
Assign(Subor, 'MOJE.TXT');
Keď je už názov súboru určený, je na čase otvoriť ho. V Pascale existujú tri možnosti jeho otvorenia - na čítanie, zapisovanie a pripisovanie. Tretí spomínaný je dostupný len pre textové súbory. Spôsob práce uvediem pre každý typ súboru zvlášť.
Začneme s textovými súbormi, keďže sú asi najjednoduchšie na pochopenie. Ich využitie nájdeme napr. pri tvorbe textového editora, ukladaní jednoduchých hodnôt do konfiguračného súboru a pod.
Textový súbor otvoríme jednou z procedúr:
Reset
- ak z neho potrebujeme čítať. Súbor už musí na disku existovať.Rewrite
- kvôli zapisovaniu. Ak súbor nejestvuje, vytvorí sa. Pokiaľ však existuje, prepíše sa a stratíme jeho pôvodný obsah!Append
- pre pripisovanie na koniec súboru. Ten už musí existovať.Parametrom týchto procedúr je vždy premenná symbolizujúca súbor (typ text
).
Rewrite(Subor);
Po otvorení môžeme do súboru zapisovať, čítať z neho a pod. Procedúra ReadLn(subor, riadok)
prečíta riadok zo súboru subor a zapíše ho do premennej riadok. Posunie sa ukazovateľ (predstavme si ho ako kurzor), takže pri ďalšom volaní tejto procedúry sa číta vždy ďalší a ďalši riadok.
WriteLn(subor, riadok)
zapíše do súboru hodnotu druhého parametra a vytvorí nový riadok.
Obdobne fungujú procedúry Read
a Write
.
Tu je jednoduchý príklad. Úlohou je vypísať obsah textového súboru na obrazovku. Použijeme pri tom funkciu Eof(súbor)
, ktorá vráti true
, ak bol dosiahnutý koniec súboru. Close(súbor)
zatvorí súbor.
program subory; var Subor: Text; riadok: string; begin {priradime premennej konkretny subor} Assign(subor, 'C:\MOJE.TXT'); {otvorime ho na citanie} Reset(subor); {kym nie je koniec suboru} while not Eof(subor) do begin {precitame riadok zo suboru} ReadLn(subor, riadok); {zapiseme riadok na obrazovku} WriteLn(riadok); end; {zatvorime subor} Close(subor); end.
Používajú sa najmä pri operáciách, kde nás nezaujíma, čo konkrétne je v súbore uložené - napríklad na kopírovanie súborov.
Na otvorenie používame tieto procedúry:
Reset
- otvorí súbor (už existujúci) na čítanie aj zápis.Rewrite
- otvorenie na čítanie a zápis. Neexistujúci súbor sa vytvorí, jestvujúci sa prepíše.Spomínané procedúry majú dva parametre. Prvý symbolizuje daný súbor (typ file
) a druhý, celočíselný, udáva veľkosť bloku dát.
Miesto procedúr Read
a Write
tu používame BlockRead
a BlockWrite
. Tie majú 3 povinné parametre - súbor, buffer (ľubovoľná pomocná premenná), počet bytov zabraných bufferom. Ten zistíme funkciou SizeOf(premenná)
. Do štvrtého (nepovinného) parametra sa uloží počet prečítaných / zapísaných záznamov.
Je tu dosť veľa teórie, ale iste viac pochopíte z príkladu - už spomínané kopírovanie súborov:
program kopiruj; var zdroj, ciel: File; {buffer bude pole 512 znakov} buffer: array[1..512] of char; precitane: integer; begin {zdrojovy subor otvorime na citanie} Assign(zdroj, 'C:\ZDROJ.BIN'); Reset(zdroj, 1); {cielovy na pisanie} Assign(ciel, 'C:\CIEL.BIN'); Rewrite(ciel, 1); {postupne citame z 1. a zapisujeme do 2. suboru} repeat {zo zdroja precitame max. 512 bytov, ulozime ich do buffera, premenna PRECITANE bude obsahovat pocet skutocne precitanych bytov} BlockRead(zdroj, buffer, SizeOf(buffer), precitane); {buffer zapiseme do ciela} {velkost buffera v bytoch = PRECITANE} BlockWrite(ciel, buffer, precitane); until precitane = 0; Close(zdroj); Close(ciel); end.
Dalo by sa to aj jednoduchšie, ale tento spôsob by mal byť pomerne rýchly.
Môžeme ich použiť, ak potrebujeme v binárnej forme ukladať viacero záznamov s rovnakou štruktúrou - napr. rodné čísla, adresy a pod. Deklarácia je nasledujúca:
var subor: file of typ_premennej;
Na otváranie sú určené procedúry Reset
a Rewrite
(ako pri netypovaných súboroch). Čítanie a zápis je možný vďaka procedúram Read
a Write
.
Príklad: Prvý program zapíše do súboru čísla zadané z klávesnice. Po zadaní a zapísaní nuly sa program ukončí.
program citaj; var cislo: integer; subor: File of integer; begin {otvorime a prepiseme subor} Assign(subor, 'C:\CISLA.BIN'); Rewrite(subor); repeat {precitame cislo z klavesnice} ReadLn(cislo); {zapiseme ho do suboru} Write(subor, cislo); {zadanim nuly sa program ukonci} until cislo = 0; Close(subor); end.
Druhý ich zas z tohto súboru prečíta a vypíše na obrazovku.
program pis; var cislo: integer; subor: File of integer; begin {otvorime subor} Assign(subor, 'C:\CISLA.BIN'); Reset(subor); {kym nie je koniec suboru} while not Eof(subor) do begin {precitame cislo zo suboru} Read(subor, cislo); {vypiseme cislo na obrazovku} WriteLn(cislo); end; Close(subor); end.
Ak potrebujeme zistiť, či daný súbor už existuje, vo FreePascale použijeme funkciu FileExists(názov_súboru)
z jednotky SysUtils
.
V TurboPascale je situácia zložitejšia. Musíme vypnúť kontrolu vstupno-výstupných chýb direktívou prekladača {$I-}. Potom sa pokúsime otvoriť súbor na čítanie. Ak sa hodnota funkcie IOResult
(chybový kód poslednej vstupno-výstupnej operácie) rovná nule, súbor existuje - nebola zaznamenaná žiadna chyba.
program exist; var subor: file; begin Assign(subor, 'C:\SKUSKA.BIN'); {vypneme kontolu chyb} {$I-} {pokusime sa otvorit subor} Reset(subor); {podla hodnoty chyboveho kodu vypiseme, ci subor existuje} if IOResult = 0 then writeln('Subor existuje.') else writeln('Subor neexistuje.'); {opat zapneme kontrolu chyb} {$I+} end.
Všimnite si, že ak za zloženou zátvorkou { nasleduje dolár $, už to nie je poznámka, ale direktíva prekladača.
Tu je zopár užitočných procedúr a funkcií:
Erase(súbor)
- zmaže súbor z disku. Parametrom je premenná typu súbor. Ten už musí byť priradený cez Assign
, ale ešte nie otvorený (pomocou Reset
, Rewrite
,...).FilePos(súbor)
- vráti aktuálnu pozíciu v otvorenom súbore (nesmie byť textový).FileSize(súbor)
- vráti celkový počet záznamov v otvorenom súbore (ten nesmie byť textový).Rename(súbor, nový_názov)
- premenuje priradený (ale ešte nie otvorený) súbor na nový_názov.Seek(súbor, pozícia)
- posunie ukazovateľ v otvorenom súbore na záznam s danou pozíciou. Súbor nesmie byť textový.