Ausschnitt aus der Ada-Version des Buchs Objektorientiertes Plug und Play
© Prof. Dr. Andreas Solymosi

Direkte Dateien

Eine Variation des Assoziativspeichers ist die direkte Datei . Der Schlüssel wird hier nicht vom Benutzer angegeben, sondern wird beim Eintragen vom Paket erzeugt und dem Benutzer zurückgegeben. Mit Hilfe dieses Schlüssels kann er dann sein Element wiederfinden. Die Daten werden, wie bei einer sequentiellen Datei, in der Reihenfolge der Eintragung, d.h. sequentiell gespeichert (typischerweise ist der Schlüssel eine Folgenummer). Neben der direkten Positionierung mit dem Schlüssel besteht die Möglichkeit, die Daten sequentiell zurückzulesen:

generic
	type TElement is private;
package GDir_Datei is
	type TDir_Datei is limited private; -- wird leer angelegt
	type TSchluessel is private; -- kopier- und vergleichbar
	procedure Alles_loeschen (Datei: out TDir_Datei); -- macht die Datei leer, bereit zum Beschreiben
	procedure Zuruecksetzen (Datei: in out TDir_Datei); -- macht die Datei bereit zum Lesen
		 -- trägt Element an das Ende der Datei ein, gibt Schluessel zurück; nur im Schreibmodus:
	procedure Eintragen (Datei: in out TDir_Datei; Element: in TElement;
		Schluessel: out TSchluessel); -- raises:
	ESpeicher_voll, ELesemodus: exception; -- Ausnahmen wie bei TSeq_Datei
	procedure Positionieren (Datei: in out TDir_Datei; Schluessel: in TSchluessel); -- raises:
	EDateiende, ESchreibmodus: exception;
	procedure Naechstes_Element (Datei: in out TDir_Datei); -- raises EDateiende, ESchreibmodus;
	function Ende_der_Datei (Datei: TDir_Datei) return Boolean; -- raises ESchreibmodus;
	function Aktuelles_Element (Datei: TDir_Datei) return TElement;
		-- raises EDateiende, ESchreibmodus;
	... -- Kopieren und Gleichheit wie üblich

Im Gegensatz zum Assoziativspeicher wird also die direkte Datei nur mit einem Parametertyp TElement ausgeprägt. Der Schlüsseltyp wird zusammen mit dem ADT exportiert.


Direkte Dateien in Ada

Ähnlich wie Sequential_IO wird die Paketschablone Direct_IO mit jedem Ada-Compiler ausgeliefert. Aus dem folgenden Ausschnitt seiner Schnittstelle sind die Unterschiede zum obigen Dateipaket ersichtlich:

generic
	type Element_Type is private;
package Direct_IO is ... -- ähnlich wie Sequential_IO, zusätzlich noch:
type File_Mode is (In_File, Inout_File, Out_File); -- Öffnungsmodus für Ein- und Ausgabe auch möglich
	type Positive_Count is ... -- implementierungsabhängiger Schlüsseltyp, eine Ganzzahl
	procedure Write (File: in File_Type; Item: in Element_Type); -- sequentielles Schreiben
	procedure Write (File: in File_Type; Item: in Element_Type; From: in Positive_Count); -- direkt
	procedure Read ... -- ähnlich, aber Item: out Element_Type
	procedure Set_Index (File : in File_Type; To: in Positive_Count); -- positioniert auf den Index To
	function Index (File : in File_Type) return Positive_Count; -- liefert die aktuelle Position
		...

Eine direkte Standarddatei kann nicht nur für Lesen oder Schreiben, sondern mit Inout_File für beides gleichzeitig geöffnet werden. Sie kann somit auch fortgeschrieben (d.h. nach dem Lesen weiterbeschrieben) werden. Beim Schreiben erhält man die Position nicht von Write in einem out-Parameter, sondern vom Aufruf der Funktion Index zurück. Mit Write ist nicht nur sequentielles Beschreiben möglich, sondern auch die Angabe einer Position; somit können früher eingetragene Elemente auch überschrieben werden.

Vor der Benutzung muß diese Paketschablone für den Basistyp ausgeprägt werden. Wenn die Datei mit Inout_File eröffnet wird, kann sie wie eine direkte Datei benutzt werden:

with Direct_IO;
	...
	type TBasis is ... -- ein beliebiger Datentyp (oft ein Verbundtyp)
	package MBasis_IO is new Direct_IO (Element_Type => TBasis);
	Datei: MBasis_IO.File_Type;
	Puffer: TBasis;
	Index: MBasis_IO.Positive_Count;
begin
	MBasis_IO.Open (File => Datei, Mode => MBasis_IO.Inout_File, Name => "DATEI.DAT");
		...
	Index := MBasis_IO.Index (File => Datei); -- oder Index anders ermitteln
	MBasis_IO.Read (File => Datei, Item => Puffer, From => Index); -- direktes Lesen
		... -- Daten im Puffer bearbeiten
	MBasis_IO.Set_Index (File => Datei, To => Index);
	MBasis_IO.Write (File => Datei, Item => Puffer); -- Daten zurückschreiben (direktes Schreiben)
		 ...

Die von Direct_IO ausgelösten Ausnahmen wurden für die sequentiellen Dateien aufgelistet.

Übung: Entwickeln Sie einen menügesteuerten Testtreiber für das Standard-Paket Direct_IO. Prägen Sie es für Ihren Lieblingsdatentyp aus und ermöglichen Sie dem Bediener, Daten sequentiell zu schreiben, sowie sequentiell und direkt zu lesen. Lassen Sie hierfür nach dem sequentiellen Schreiben den aktuellen Index über die Ausprägung von GAusgabefenster für Positive_Count anzeigen. Erlauben Sie dem Bediener über zwei verschiedene Menüpunkte sowohl von der aktuellen Position, wie auch nach Positionieren zu lesen.


© Prof. Dr. Andreas Solymosi

Rückmeldungen bitte an den Autor solymosi@tfh-berlin.de

Leitseite des Autors