Dateien in Pascal

Ohne Dateien könnte man keine Daten speichern etc. Dieser Text soll einen kurzen Überblick geben, wie man mit Dateien in Pascal umgeht.
Dabei bezieht sich dieser Text auf Turbo Pascal!
In FreePascal und Delphi gibt es geringfügige Unterschiede, Standard Pascal behandelt Dateien anders.

Dateien in Turbo Pascal

Für Textdateien gibt es in Pascal den Typ Text. (var f: Text;)
Befehl Beschreibung Beispiel
Assign Ordnet einer Variablen von Typ Text eine Datei zu. Assign(f,’c:\hallo.dat’);
Reset Öffnet die Datei (nur lesen) Reset(f);
ReWrite Erstellt / überschreibt die Datei (nur schreiben) ReWrite(f);
WriteLn Schreibt eine Zeichenkette in die Datei WriteLn(f,’Hallo’);
ReadLn Liest eine Zeile aus der Datei in eine String-Variable ReadLn(f,stringvar);
Close Schließt die Datei (nicht vergessen!!!) Close(f);
IOResult Liefert Fehlercode im Modus $I- zurück if IOResult<>0 then ...;
Rename Benennt eine geschlossene Datei um Rename(f,’newname’);
Erase Löscht eine geschlossene Datei Erase(f);

Ablauf bei Dateioperationen:

  1. Definieren einer Variablen vom Typ Text
  2. Variable einer Datei zuordnen (Assign)
  3. Datei öffnen (Reset) bzw. neu schreiben (ReWrite )
  4. Dateiinhalt lesen (ReadLn) bzw. schreiben (WriteLn)
  5. Datei schließen (Close)!!

Fehler bei Dateioperationen:

Fehler können zum Beispiel dann auftreten, wenn ein Datenträger fehlerhaft ist oder versucht wird, auf eine schreibgeschützte Diskette zu schreiben. Auch bei ungültigen Dateinamen gibt es Fehler.

Diese Fehler führen normalerweise dazu, daß das Programm eine Fehlermeldung ausgibt und sich dann beendet. Dies ist aber für den Programmnutzer nicht schön, da er sich zum Beispiel vertippt haben könnte. Deshalb sollte man in Turbo Pascal vor Datei-Aktionen (außer bei Assign , das gefahrlos ist) den Compiler-Schalter $I ausschalten und danach wieder einschalten.

Compiler-Schalter stehen im Quelltext und sehen wie Kommentare aus, nur daß das erste Zeichen hinter dem Kommentaranfang ein $ ist. ( {$I-} zum Ausschalten von automatischer Fehler-Überprüfung und {$I+} zum Einschalten. Auch sind (*$I-*) und (*$I+*) möglich.) Allerdings sollte man dann nach jeder I/O-Aktion testen, ob IOResult gleich 0 ist. Ist dies nicht der Fall, so liegt ein Fehler vor.

Weitere Dateiprozeduren aus der Unit Dos ("uses Dos;" ins Programm aufnehmen):

(hier wird allerdings das Programm bei Fehlern weder abgebrochen noch wird IOResult verändert, sondern die Variable DosError aus der Unit Dos wird dann auf einen Wert ungleich 0 gesetzt - welche Werte wann, steht in der Online-Hilfe von Turbo Pascal)
 
Befehl Beschreibung Beispiel
GetFAttr Liest die Dateiattribute von f aus GetFAttr(f,attribs);
SetFAttr Setzt die Dateiattribute von f SetFAttr(f,Hidden);
GetFTime Liest die Zeit einer Datei (siehe UnpackTime) GetFTime(f,time);
SetFTime Setzt die Zeit einer Datei (sieht PackTime) SetFTime(f,time);

Weitere Prozeduren / Funktionen:

Befehl Beschreibung Beispiel
DiskSize Liefert die Größe eines Laufwerks in Byte (unit Dos) DiskSize(Byte(‘C’)-64);
DiskFree Liefert den freien Platz eines Laufwerks in Byte (unit Dos) DiskFree(Byte(‘C’)-64);
ChDir Wechselt ins angegebene Verzeichnis ChDir(‘c:\windows’);
GetDir Ermittelt das aktuelle Verzeichnis auf einem Lausfwerk GetDir(Byte(‘C’)-64,verz);
MkDir Erstellt ein Verzeichnis MkDir(‘Temp’);
RmDir Löscht ein Verzeichnis RmDir(‘Temp’);

Nicht-Textdateien in Turbo Pascal:

Wenn man zum Beispiel 100 lange Zahlen (Longints) abspeichern will, benutzt man typisierte Dateien. Diese werden mit var f: File of Typ; definiert. Dieser Datei-Typ hat den Vorteil, daß die Daten dort genauso gespeichert werden wie im Arbeitsspeicher. Longints nehmen zum Beispiel immer 4 Bytes ein, während sie ausgeschrieben bis zu 10 Bytes belegen. Bei noch größeren Datensätzen (z.B. Arrays oder Records) ist der Speichervorgang außerdem einfacher. Das Lesen und Schreiben funktioniert mit Read und Write (jeweils OHNE "Ln"). Außerdem kann man mit Reset die Dateien für Lese- und Schreibvorgänge öffnen.

Einige weitere Prozeduren / Funktionen:

Befehl Beschreibung Beispiel
FileSize Liefert die Größe der Datei in Datensätzen
Die Größe in Byte erhält man nur bei File of Byte / Char (bzw. bei File of Etwas, bei dem gilt sizeof(Etwas)=1)
groesse:=FileSize(f);
Seek Setzt die momentane Lese/Schreibposition Seek(f,0);
FilePos Liest die momentane Lese/Schreibposition aktuell:=FilePos(f);
Truncate Schneidet die Datei an der Lese/Schreibposition ab Truncate(f);

Untypisierte Dateien in Turbo Pascal:

Wenn man große Dateien einlesen oder schreiben möchte, deren Inhalt kein bestimmtes Format aufweist (z. B. beim Kopieren von einer Datei), benutzt man untypisierte Dateien. Sie werden einfach durch var f: File; definiert. Für diese Dateien gibt es spezielle Ein- und Ausgaberoutinen (Read und Write funktionieren nicht). Auch sind die Befehle Reset und ReWrite etwas abgewandelt: Sie haben neben der Dateivariablen noch den Parameter RecSize, der als Faktor für nachfolgende Dateiaktionen dient.

Mittels BlockWrite(file, buf, count, result) schreibt man, und BlockRead(file, buf, count, result) liest aus der Datei, die im Parameter file übergeben wird. Der Parameter buf übernimmt die Speicherung der gelesenen Daten. In count gibt man die Größe der zu lesenden / schreibenden Daten an. Wie viele Bytes tatsächlich gelesen werden sollen, ergibt sich aus count*RecSize (muß zwischen 1 und 65535 liegen). Der Parameter Result liefert die Anzahl der tatsächlich gelesenen / geschriebenen Daten. Wenn Result ungleich count ist, ist ein Fehler aufgetreten, den man selbst überprüfen muß. Auch im Modus {$I+} bricht das Programm nicht ab. Wenn man allerdings den Parameter Result wegläßt, was zulässig ist, entsteht eine Fehlermeldung, wenn nicht {$I-} angegeben ist.

Von RecSize werden noch FilePos, FileSize und Seek beeinflußt.

Schreibgeschützte Dateien

Manchmal möchte man schreibgeschützte Dateien auslesen und wundert sich, daß es nicht funktioniert. Das liegt dann an der Variablen FileMode. Normalerweise ist FileMode gleich 2 (lesen und schreiben). Diese Variable muß man dann auf 0 setzen (nur lesen). Der Wert 1 bedeutet nur schreiben.

FreePascal und Delphi

In FreePascal und Delphi gibt es geringfügige Abweichungen zu Turbo Pascal. Es gibt in Delphi nämlich die Funktionen Close und Assign für andere Dinge. Daher heißt das TP-Assign in Delphi auch AssignFile (Close heißt entsprechend CloseFile) - in FreePascal gilt dies nur, wenn man den ObjFPC-Mode nutzt. Des weiteren heißen die Konstanten, die die Datei-Attribute beschreiben, anders: sie haben ein vorangestelltes "fa" (also z.B. faHidden). Ansonsten ändert sich nichts, es kommen nur noch neue Funktionen aus der Unit SysUtils hinzu. Des weiteren eröffnet sich mit try...except / finally eine neue Möglichkeit der Fehlerbehandlung.

Standard Pascal

In Standard Pascal wird mit den Funktionen get und put in Dateien geschrieben bzw. aus ihnen gelesen. Zuvor muß man den Daten aus der Datei mit f^:=irgendwas den zu schreibenden Wert zuweisen bzw f^ enthält den gelesenen Wert. Außerdem müssen die Dateien im Programmkopf deklariert werden. Wer mehr wissen will, lese doch ein Buch über Standard Pascal.



Dieses Dokument erhebt weder Anspruch auf Vollsträndigkeit noch auf Richtigkeit. Ich empfehle immer zusätzlich die Benutzung der Dokumentation zum jeweiligen Compiler!
Fehler / Ergänzungen bitte an mich mailen (Adresse: pascal (at) behrenhoff (Punkt) de)