Die Community zu .NET und Classic VB.
Menü

Random Dateien

 von 

Übersicht 

Hier der zweite Teil zum Thema Datei-Handling von Markus Zeichner. Diesmal wird der Umgang mit typisierten, besser bekannt als Random-, Dateien erläutert. Sie bieten unter VB, meines Wissens nach, den schnellst möglichen Dateizugriff überhaupt.

Mit freundlichen Grüßen
i.A. Götz Reinecke,

Typisierte Dateien  

Typisierte Dateien sind eine Art von Textdateien die sich jedoch besonderes zum Speichern von numerischen Daten und Nutzertypen eignen.
Diese Art von Dateien besitzen eine konstante Datensatzlänge, zwischen den einzelnen Datensätzen ist kein Trennzeichen vorhanden. Man muss also wissen wie groß ein Datensatz ist.
Für das Speichern von Zeichenketten ist eine typisierte Datei weniger geeignet, da auch für ein Leerstring die einmal definierte Anzahl von Zeichen freigehalten wird.

Wie kann ich eine typisierte Datei öffnen?  

Auf eine typisierte Datei kann gleichzeitig im Schreibmodus als auch im Lesemodus zugegriffen werden. Das öffnen eine typisierten Datei geschieht mit:

Open Dateiname For Random As Dateinummer Len = Satzlänge

Parameter Beschreibung
Dateiname Pfad und Dateiname der zu öffnenden Datei.
Dateinummer Eine gültige Dateinummer im Bereich von 1 bis 511 [einschließlich]. Mit der FreeFile-Funktion erhält man die nächste verfügbare Dateinummer. Unter dieser Nummer erfolgen dann alle weitere Zugriffe des Programms auf die Datei.
Satzlänge Zahl kleiner oder gleich 32.767 [Bytes] die die Datensatzlänge angibt.

Was hier vielleicht noch näher erklärt werden sollte, ist der Parameter Len. Dieser bestimmt die Datensatzlänge, also die Länge der Daten in "einer Zeile". Stimmt die Datensatzlänge nicht mit der tatsächlichen Länge überein, erhält man beim Lesen der Datei eine Fehlermeldung, und im schlimmstem Falle falsche Werte zurück. Wird keine Länge angegeben, legt VB automatisch 128 Byte fest.

Private Type Datensatz
  Nr As Long
  Name As String * 20
  Vorname As String * 20
End Type

'...

Dim FN As Integer
Dim Data As Datensatz

  FN = FreeFile
  Open "C:\Text.txt" For Random As FN Len = Len(Data)

'...

Listing 1

Zuerst wird ein Datentyp definiert der sich aus einem Longwert, einem String der Größe 20 Zeichen und noch einem String der Größe 20 Zeichen zusammensetzt. Danach wird der Variablen Data dieser Datentyp zugewiesen. Mit dem Len(Data) wird die Länge der Variablen bestimmt und dem Len-Parameter übergeben. Diesen Beispiel werden wir später noch ein bißchen erweitern.

Was ist der Datensatzzeiger?  

Bei typisierten Dateien gibt es eine Art Zeiger der immer auf den aktuellen Datensatz zeigt. Nach dem Öffnen der Datei zeigt der Datensatzzeiger auf den ersten Datensatz. Der erste Datensatz bei typisierten Dateien hat immer die Nummer 1. Wird aus der Datei gelesen oder werden Daten geschrieben, wird der Datensatzzeiger immer um ein Datensatz weiter bewegt. D.h wenn man den 20. Datensatz liest zeigt der Datensatzzeiger nach dem Lesevorgang auf den Datensatz 21. Das ist wichtig zu wissen wenn man in einer Schleife lesen will.

Will man jetzt ab einem bestimmten Datensatz lesen, kann auch der Datensatzzeiger direkt auf den Datensatz bewegt werden. Dazu gibt es einen einfachen Befehl:

Seek Dateinummer, Datensatznummer

Eine genauere Beschreibung ist hier wohl nicht mehr nötig. Sollte der Zeiger auf ein Datensatz gesetzt werden der noch nicht existiert, kommt es zur keiner Fehlermeldung !!! Es ist dadurch möglich Datensätze zu lesen die es gar nicht gibt. Ob dabei jedoch was sinnvolles rauskommt ist fraglich. Anderes ist es beim Speichern. Hier könnte sich die Tatsache durchaus nützlich machen, allerdings kann man nicht sagen welche Daten zwischen dem letztem vorhandenem Datensatz und dem neuem enthalten sind. Der Speicherplatz für mögliche Daten wird aber reserviert und bis zum ersten Beschreiben der "leeren" Datensätze steht dort nur Müll!

Wenn man jetzt aber umgekehrt die aktuelle Datensatznummer wissen will ? Dann nutzt man Seek als Funktion:

Datensatznummer = Seek (Dateinummer)

Hier spare ich mir auch die Beschreibung, aber im Zusammenhang möchte ich noch zeigen wie die Anzahl der vorhandenen Datensätze heraus zu bekommen ist, nur ein bißchen Mathematik. Und zwar:

Mit dem Öffnen der Datei...

Open Dateiname For Random As Dateinummer Len = Len(Data)
Anzahl = LOF(Dateinummer) / Len(Data)

Oder ohne öffnen der Datei...

Anzahl = FileLen(Dateiname) / Len(Data)

In beiden Fällen enthält die Variable Anzahl die Menge der Datensätze.

Datensätze schreiben  

Das Schreiben ist wie bei den Textdateien gar nicht so schwer. Der zugehöriger Befehl dazu ist:

Put Dateinummer, [Datensatznummer], Variable

Parameter Beschreibung
Dateinummer Eine gültige Dateinummer im Bereich von 1 bis 511 [einschließlich]. Mit der FreeFile-Funktion erhält man die nächste verfügbare Dateinummer. Unter dieser Nummer erfolgen dann alle weitere Zugriffe des Programms auf die Datei.
Datensatznummer Nummer des Datensatzes in den Dateien geschrieben werden sollen. Ist nicht zwingend erforderlich.
Variable Name der Variablen, die die auf den Datenträger zu schreibenden Daten enthält.

Jetzt machen wir an dem vorherigem Beispiel weiter:

Private Type Datensatz
  Nr As Long
  Name As String * 20
  Vorname As String * 20
End Type

'...

Dim FN As Integer
Dim Data As Datensatz

  FN = FreeFile

  Open "C:\Text.txt" For Random As FN Len = Len(Data)
    Data.Nr = 1
    Data.Name = "Testname1"
    Data.Vorname = "Testvorname1"

    Put FN, , Data

    Data.Nr = 2
    Data.Name = "Testname2"
    Data.Vorname = "Testvorname2"

    Put FN, , Data
  Close FN

Listing 2

So, hier arbeiten wir weiter mit dem selbstdefiniertem Datentyp, weisen der Variable die entsprechender Daten zu und speichern das ganze in die Datei. Die Daten werden in den aktuellen Datensatz geschrieben, dann automatisch der Datensatzzeiger erhöht. Man könnte das ganze auch so machen:

Open "C:\text.txt" For Random As FN Len = Len(Data)
  Data.Nr = 1
  Data.Name = "Testname1"
  Data.Vorname = "Testvorname1"

  Put FN, 1, Data

  Data.Nr = 2
  Data.Name = "Testname2"
  Data.Vorname = "Testvorname2"
  Put FN, 2, Data
Close FN

Listing 3

Hier sagen wir direkt in welchen Datensatz geschrieben werden soll [Put FN,1,...]. Je nach dem welche Möglichkeit man nutzt, werden die Daten in die Datensätze geschrieben. Die zwei letzten Beispiele schreiben in die gleichen Datensätze, betrachten wir jetzt einen ähnlichen Fall:

Open "C:\text.txt" For Random As FN Len = Len(Data)
  Seek FN, 10
  Data.Nr = 1
  Data.Name = "Testname1"
  Data.Vorname = "Testvorname1"

  Put FN, , Data

  Data.Nr = 2
  Data.Name = "Testname2"
  Data.Vorname = "Testvorname2"

  Put FN, , Data
Close FN

Listing 4

Hier werden die Daten in die Datensätze 10 und 11 geschrieben, da wir vor dem Schreiben den Satzzeiger auf die Position 10 gestellt haben. Und zur Verwirung noch ein weiteres Beispiel:

Open "C:\text.txt" For Random As FN Len = Len(Data)
  Seek FN, 10

  Data.Nr = 1
  Data.Name = "Testname1"
  Data.Vorname = "Testvorname1"

  Put FN, 1, Data

  Data.Nr = 2
  Data.Name = "Testname2"
  Data.Vorname = "Testvorname2"

  Put FN, , Data
Close FN

Listing 5

Gleich dazu eine Frage. In welche Datensätze werden die zwei Put-Ausgaben gemacht?
Sind es:

a) 10 und 11
b) 1 und 10
c) 1 und 2
d) 10 und 2

Wer kann diese Frage beantworten?

Versuchen wir den Code zur Analysieren. Erstens wird die Datei geöffnet, das soll außer Acht bleiben. Dann wird der Satzzeiger auf den Datensatz 10 verschoben, und der Variable Data einige Werte zugewiesen. Jetzt wird die Variable mit dem Put-Befehl in dem erstem Datensatz gespeichert, und der Satzzeiger automatisch auf den nächsten Datensatz gebracht. Wieso werden die Daten im ersten Datensatz gespeichert?

Schauen wir uns den Put-Befehl genauer an.

Put FN, 1, Data

Was heißt das genauer?

Put schreibe
FN in die Datei mit der Datennummer die in der Variablen FN steht
1 in den ersten Datensatz
Data die Daten die Data enthält, und verschiebe den Satzzeiger um eins.

Jetzt zeigt der Satzzeiger auf zwei. Weiter im Code werden der Data-Variable wieder neue Werte zugewiesen, und mit dem nächstem Put-Befehl in den aktuellen, also auf den der Datensatzzeiger zeigt, geschrieben. Da der Datensatzzeiger auf den Datensatz zwei zeigt werden die Daten in den Datensatz zwei geschrieben. Und somit ist die Antwort C richtig. Sie haben gewonnen !!!

Datensätze aus typisierten Dateien lesen  

Jetzt lernen wir noch einen Befehl kennen und dann können wir mit typisierten Dateien umgehen. Zum Lesen benutzt man also:

Get Dateinummer, [Datensatznummer], Variable

Parameter Beschreibung
Dateinummer Eine gültige Dateinummer im Bereich von 1 bis 511 [einschließlich]. Mit der FreeFile-Funktion erhält man die nächste verfügbare Dateinummer. Unter dieser Nummer erfolgen dann alle weitere Zugriffe des Programms auf die Datei.
Datensatznummer Nummer des Datensatzes in den Dateien geschrieben werden sollen. Ist nicht zwingend erforderlich.
Variable Name der Variablen, die die auf den Datenträger zu schreibenden Daten enthält.

Dieser Befehl verhält sich gleichermaßen wie Put, nur mit dem Unterschied, daß hier Datensätze gelesen und nicht geschrieben werden. Aus diesem Grund verzichte ich hier wiederum auf eine detaillierte Beschreibung und komme gleich zur einem Beispiel. Hier wird gezeigt wird wie auf einfache Weise die Position und Größe eines Fensters beim Schließen zu speichern ist und bei erneuten Starten des Programms, das Fenster wieder an der letzte Position, in der letzten Größe öffnet.

Private Type Koordinaten
  X As Long
  Y As Long
End Type

'...

Public Sub Form_Load()
  If FileExist("WindowPrefs.dat") Then
    Dim Fn As Integer
    Dim Data As Koordinaten

      Fn = FreeFile
      Open "WindowPrefs.dat" For Random As Fn Len = Len(Data)
        Get Fn, , Data
        Form1.Top = Data.X
        Form1.Left = Data.Y

        Get Fn, , Data
        Form1.Width = Data.X
        Form1.Height = Data.Y
      Close Fn
  End If
End Sub

'...
' hier geht das Programm weiter
'...

Public Sub Form_Unload(Cancel As Integer)
  Dim Fn As Integer
  Dim Data As Koordinaten

    Fn = FreeFile
    Open "WindowPrefs.dat" For Random As Fn Len = Len(Data)
      Data.X = Form1.Top
      Data.Y = Form1.Left
      Put Fn, , Data

      Data.X = Form1.Width
      Data.Y = Form1.Height
      Put Fn, , Data
    Close Fn
End Sub

'...
' und noch eine Funktion mit der man das Vorhandensein
' eine Datei überprüft

Public Function FileExist(Dateiname As String) As Boolean
  On Error Goto Fehler

  FileExist = Dir$(Dateiname) <> ""
  Exit Function
Fehler:
  FileExist = False
  Resume Next
End Function

Private Sub Command1_Click()
  Unload Me
End Sub

Listing 6

Dieser Code funktioniert jedoch nur dann einwandfrei, wenn die StartUpPosition des Fenster auf 0 oder 3, und die WindowState-Eigenschaft auf 0 steht. Was passiert in dem Code genauer?

In der Form_Load Prozedur wird erst geprüft ob die Datei WindowPrefs.dat überhaupt schon existiert [es kann ja sein das der User die Datei gelöscht hat]. Ist die Datei nicht vorhanden wird das Fenster ganz normal angezeigt. Ist sie jedoch vorhanden, werden erst die obere und linke Position des Fensters gelesen und in die zugehörigen Eigenschaften gespeichert, dann die Breite und die Höhe des Fensters gelesen und wiederum in die entsprechenden Eigenschaften geschrieben, und die Datei geschlossen. Beim Schließen des Fensters werden die entsprechenden Fenstereigenschaften in die Datei geschrieben. Falls die Datei noch nicht existiert, wird sie automatisch angelegt.

Die Funktion FileExist ist eine universale Funktion mit deren Hillfe man ganz leicht überprüfen kann, ob eine Datei schon existiert, ist das der Fall, liefert FileExist den Wert True, oder wenn die Datei noch nicht vorhanden ist den Wert False.

Komplettes Tutorial als PDF-Datei [479000 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.