Home » Tipps & Tricks » Sonstiges » Sonstiges » Typisierte Dateien

Typisierte Dateien

Typisierte Dateien sind ein Art von Dateien, die immer wieder einen gleichen Typ von Daten in der Datei speichern. Die Anzahl der Daenfelder ist hierbei unbeschränkt, aber ein Datensatz muss immer gleich Groß sein. Um Daten in einer typisierten Datei zu speichern, muss man zuerst eine Variable für die Datei unter var deklariert werden. Tradionell heißt eine Datei immer f:

var
  f: file of Integer;

Der Typ (in diesem Beispiel Integer) ist natürlich austauschbar. Wichtig ist hierbei jedoch, dass der Speicherbedarf des Typen konstant ist, außerdem ist es relativ nutzlos, einen Pointer zu speichern, da die Adresse wohl beim nächsten öffnen der Datei in Speichernirvana zeigt. Als nächstes muss die Variable f einer Datei zugeordnet werden. Dies geschieht über die Procedure AssignFile:

AssignFile(f, 'c:\MeineDatei.dat');

Bei AssignFile sind auch relative Namesangaben für die Datei möglich, falls diese sich immer in dem Ordner oder einem Unterordner der EXE-Datei befindet.Jetzt muss die Datei angelegt werden, oder falls sie schon angelegt ist, zum Überschreiben bereitgemacht werden. Diese Aufgabe übernimmt die Procedure Rewrite, die auch gleich die Datei öffnet:

Rewrite(f);

Nach der Verwendung von Rewrite ist f immer eine leere, geöffnete Datei.Jetzt kann man darangehen, Datensätze zu speichern. Diese Aufgabe übernimmt die Procedure Write. Write benötigt mindestens 2 Parameter: die Datei (f) und einen zu schreibenden Datensatz. Bei Write können auch mehrere Datensatze als Parameter übergeben werden:

Buffer:=5;
Write(f,Buffer);
Buffer:=7;
Write(f,Buffer);

Wäre also identisch mit:

Buffer:=5;
Buffer2:=7;
Write(f,Buffer,Buffer2);

Anschließend muss die Datei noch geschlossen werden. Dies sollte direkt nach dem Lesen geschehen, und nicht am Programmende:

CloseFile(f);

Das Auslesen der Daten geschieht sehr ähnlich wie das schreiben:

var
  f: file of Integer;
  int1, int2, int3: Integer;
begin
  AssignFile(f,'c:\MeineDatei.dat');
  Reset(f);
  Read(f,int1);
  Read(f,int2,int3);
  CloseFile(f);
end;

Die Veränderungen hierbei sind, dass die Methode Rewrite, die den Inhalt der Datei löscht, nicht benutzt wird. Anstelle dessen wird die Datei mit Reset geöffnet. Reset setzt außerdem den Zeiger auf den Aktuellen Datensatz auf den ersten. Die Methode Write wurde außerdem durch Read ersetzt.Häufig zu finden ist auch die Funktion eof (End Of File). Sie benötigt einen Parameter, die Datei f, und der Rückgabewert ist boolean, wenn nun keine Daten mehr zu lesen sind (man also am Ende der Datei angelangt ist). Dieser Code liest eine Typisierte, beliebig lange Char-Datei aus und fügt sie zu einem String zusammen:

var
  f: file of Char;
  s: string;
  Buffer: char;
begin
  AssignFile(f,'c:\MeineDatei.dat');
  Reset(f);
  while not eof(f)   //solange noch Daten zu lesen sind
    do begin
      read(f,Buffer);
      s:=s+Buffer;
    end;
  CloseFile(f);

Typisierte Dateien können auch zum schreiben mit Reset geöffnet werden. Dann wird der bisherige Inhalt aber nur Datensatz für Datensatz mit Write gelöscht. Will man einen oder mehrere Datensätze weiter, kann man mit Read einfach Daten einlesen, diese aber nicht verwenden. Um wieder an die erste Position der Datei zu gelangen, muss man einfach Reset aufrufen.Mit Hilfe der Methode Seek kann man an eine bestimmte Stelle in der Datei springen. Die benötigten Parameter sind die Datei und die Stelle, an die man springen will. Die erste Stelle in einer Datei ist immer 0, die letzte Stelle Stelle in einer Datei ist immer Datensätze-1. Durch Seek lassen sich auch größere Mengen an Daten verwalten und man kann schnell zu den enötigten Daten springen. Diese Prozedur zum Beispiel schreibt mehrere Integerwerte in eine Datei und liest den 5. Wert (an Stelle 4 gelegen) wieder aus und zeigt ihn an:

procedure TForm1.Button1Click(Sender: TObject);
var
  i,int: Integer;
  f: file of Integer;
begin
  AssignFile(f,'Datei.dat');        
  ReWrite(f);                        
  for i:= 1 to 7 do
    Write(f,i);                      
  Seek(f,4);                         //Springt an die 5. Stelle
  Read(f,int);                       //Ließt die 5. Stelle ein
//Gibt die Zahl an der 5. Stelle aus (Dies wird eine 5 sein)
  ShowMessage(IntToStr(Int));        
  CloseFile(f);                      //Zum Ende wieder schließen
end;

Zusammenfassend lässt sich sagen, dass typisierte Dateien Ideal sind, um mehrere gleiche Daten hintereinander aufzunehmen, besonders praktisch bei Records oder auch zum Speichern von (dynamischen) Arrays. Nicht vernünftig speichern lassen sich Objekte oder lange Strings (erlaubt sind nur die alten, kurzen Strings, da die benötigte Größe bekannt sein muss). Die Performance ist minimal langsamer als die von Streams: Auf meiner (langsamen IDE) Festplatte benötigte das Schreiben vor 100000(!) Chars bei typisierten Dateien immer etwas 750ms, Streams waren immer zwischen 5-20 ms schneller. Für viele Fälle sind typisierte Dateien leichter zu handhaben, es sei denn, die Geschwindigkeit ist sehr wichtig.