FreeBasic: Dateien

Oft, sehr oft ist es sinnvoll bestimmte Dinge in eine Datei zu schreiben oder aus einer Datei zu lesen. Dies erreicht man mit den 5 Schlüßelwörtern Open, Print, Put, Get und Input, von denen wir schon zwei aus den vorherigen Kapiteln kennen.

ArbeitsverzeichnisBearbeiten

Bevor es mit den oben erwähnten Befehle weiter geht, gibt es noch einen Punkt, der für die folgenden Befehle wichtig ist. Das Programm arbeitet mit einem Arbeitsverzeichnis, dass Arbeitsverzeichnis ist aber nicht gleich das Verzeichnis wo sich die "exe"-Datei befindet. Soll in den folgenden Befehlen eine z.B. ".txt"- Datei geöffnet werden, dann wird nur der Name der Datei mit der Endung ".txt" eingegeben und das Programm sucht in seinem Arbeitszeichnis nach dieser Datei. Das Programm würde einen Fehler bringen, wenn statt des Dateinamens ein Pfad mit Dateinamen angegeben werden würde. Deswegen muss ihn vorher das Arbeitsverzeichnis zugewiesen werden. Standardmäßig ist bereits ein Arbeitsverzeichnis zugewiesen.

In Basic ist es aber möglich beides abzufragen.

Einmal mit dem Befehl "EXEPATH" kann der Pfad der "exe"-Datei abgefragt werden.

Print EXEPATH

Oder der Dateipfad kann auch einer "String"-Variablen zugewiesen werden.

Dim szPfad as string = EXEPATH

Es ist auch möglich diesen Pfad einer "String"-Variable zu übergeben.

Mit dem Befehl "CurDir" wird das aktuelle Arbeitsverzeichnis abgefragt.

Print CurDir

Auch dies kann direkt einer String-Variablen zugewiesen werden.

Dim szArbeitsverzeichnis as string = CurDir

Da es auch mal nötig sein muss, dass Arbeitsverzeichnis zu wechseln, gibt es noch einen zweiten Befehl.

CHDIR "C:\HalloWelt"

Dieser Befehl weißt dem Programm nun das neue Arbeitsverzeichnis mit dem "Pfad" "C:\HalloWelt" zu.

OpenBearbeiten

Mit Open öffnet man die Datei zur Ein/Ausgabe. Man öffnet eine bestimmte Datei in einem bestimmten Modus und gibt ihr einen Namen.

open "test.txt" for input as #1

Open ist das Schlüsselwort, darauf folgt in Anführungszeichen der Dateiname mit Endung. Das for dient der Übersichtlichkeit. Insgesamt gibt es 5 Dateimodi:

Name Beschreibung
Input Wird meistens benutzt um eine Datei mit Text Zeile für Zeile zu lesen.
Binary Wird benutzt um eine Datei binär zu öffnen zum Beispiel Bilder oder Musik.
Output Legt eine Datei zum hineinschreiben an. !!!Achtung!!! Wenn der Dateiname schon existiert wird die alte Datei überschrieben.
Append Öffnet eine Datei zum schreiben, aber hängt wenn der Name schon existiert alles ans Ende der Datei.
Random Kompliziert und für Anfänger eher uninteressant. Wird später behandelt.

Die Nummer am Ende ist hier #1. Sie wird immer mit einem # eingeleitet und ist dann wichtig für die späteren Lese- und Schreibzugriffe. Sie muss zwischen 0 und 255 liegen.

Datei Eingabe und AusgabeBearbeiten

InputBearbeiten

Im vorherigen Kapitel haben wir gesehen das man mit Input Tastatureingaben in einem String speichern kann.
Mit Input kann man aber auch aus Dateien Texte einlesen zum Beispiel aus einer .txt Datei. Hier ein Beispiel mit dem aus der gerade geöffneten Datei gelesen wird:

dim temp as string
input #1, temp

Man sieht, alles ist gleich bis auf die Dateinummer die vor die Variable kommt. Wenn man mehrere Dateien hat wird also mit der Zahl bestimmt aus welcher man jetzt lesen will.

GetBearbeiten

Get tut im Prinzip das gleiche wie Input, nur das die Daten Byte für Byte gelesen werden. Das kann nützlich sein bei Bildern, Musik, Filmen, eben allem was kein Text ist.

dim temp as byte
get #1,,temp

So wird ein Byte in die Variable temp gelesen. "Warum zwei Kommata?" wirst du dich vielleicht Fragen. Zwischen #1 und temp könnte noch ein weiterer Parameter kommen: Die Nummer des Bytes von dem gelesen werden soll. Wenn man einfach nichts schreibt, wird automatisch das Byte genommen, das eins weiter liegt als das beim letzten Lesen. Hinter temp könnte auch noch ein Parameter folgen. Dieser würde regeln wie viel gelesen werden soll, was im Zusammenhang mit Zeigern und Arbeitsspeicher eine Rolle spielt. In Beispielen wie hier kannst du diesen Parameter getrost weglassen.

PrintBearbeiten

Genau wie Input kennen wir Print bereits. Mit Print kann man nicht nur Strings ausgeben, man kann auch Strings in Dateien ausgeben.

print #1, "Test"

Wenn man bei Open nicht aufgepasst hat wird man feststellen, dass dieses Beispiel nicht Funktioniert. Man muss die Datei für Print im Modus Output geöffnet haben sonst kann man aus der Datei nur lesen.

PutBearbeiten

Put ist das Äqivalent zu Print für Binärdateien. Die Syntax ist gleich wie bei Get, nur dass geschrieben wird und nicht gelesen.

dim temp as byte = 34
put #1,,temp

Freebasic erkennt von allein, dass temp nur ein Byte groß ist. Put ist nur sinnvoll, wenn die Datei im Binärmodus geöffnet wurde. Das gilt übrigens auch für Get.

CloseBearbeiten

Es ist nicht schwer zu erraten, dass Close das Gegenstück zu Open ist. Mit Close wird also eine Datei geschlossen. Hier ein Beispiel:

open "test.txt" for input as #1
close #1

Warum sollte man eine Datei schließen? Macht FreeBasic doch von allein. Es gibt gute Gründe die dafür sprechen. Zum Beispiel kann es sein, dass Windows alle Dateioperationen verhindert, da Windows glaubt die Datei wäre noch offen. Du solltest einfach immer daran denken, eine Zeile mehr schreiben ist wirklich keine große Sache.

Länge einer DateiBearbeiten

Es kann notwendig sein, die Länge einer Datei zu kennen, warum werden wir in den Profithemen behandeln. Die Funktion Lof() gibt die länge in Byte zurück. Sie erwartet die Dateinummer mit dem '#' und funktioniert anscheinend nur unter Windows perfekt.

open "test.txt" for input as #1
print lof(#1)
sleep
close #1

Es muss natürlich auch eine Datei "test.txt" geben, um dieses Beispiel zu benutzen.

Ende einer DateiBearbeiten

Die Funktion Eof() wird gleich aufgerufen wie Lof() aber gibt nicht die länge der Datei zurück, sondern gibt -1 zurück wenn die Datei am Ende angelangt ist. Auf diese Art kann eine Datei in einer Schleife bis zu ihrem Ende Schritt für Schritt gelesen und verarbeitet werden.

open "test.txt" for input as #1
dim text as string
do 
  input #1, text
  print text
loop until eof(1) 
sleep
close #1

Wenn es eine Datei mit dem Namen "test.txt" gibt solltest du jetzt alle Zeilen einzeln ausgegeben sehen.

Eine kleine Anmerkung zum SchlussBearbeiten

Für den Binärmodus wurde hier überall der Datentyp Byte benutzt. Wenn man wirklich mit Bildern oder anderem arbeitet, wird man sich über die komischen Ergebnisse wundern. Dinge wie -100 werden auftauchen. Das liegt nicht an der Datei sondern am Datentyp. Man muss natürlich UByte benutzen um Zahlen von 0-255 zu erhalten.