Sequentielle Datei

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Eine sequentielle Datei ist eine Datei, auf deren Inhalt nur sequentiell zugegriffen werden kann, d.h. um einen bestimmten Bereich der Datei zu lesen, müssen alle vorhergehenden Daten eingelesen werden. Auch können nicht beliebige Teile der Datei überschrieben werden, sondern nur die Datei von Anfang an. Allerdings ist es möglich, zusätzliche Daten an die Datei anzuhängen, wobei aber zum Auffinden des Dateiendes ebenfalls alle Daten eingelesen werden müssen.

Datasetten-Dateien sind technisch bedingt immer sequentiell. Diskettendateien sind dagegen blockweise organisiert, sodass prinzipiell ein wahlfreier Zugriff möglich ist. Dies erfordert aber zusätzlichen Verwaltungsaufwand, den man sich bei SEQ-Dateien sparen kann.

Es folgt nun die Beschreibung von sequentiellen Dateien auf Disketten unter CBM-DOS. Diese Informationen gelten auch für PRG- und USR-Dateien, da diese sich auf Dateisystemebene nur durch die Dateitypkennung von SEQ-Dateien unterscheiden.


Eigenschaften[Bearbeiten | Quelltext bearbeiten]

Im Directory einer Diskette (hier die Datei: SPIELE) werden sequentiellen Dateien durch den Dateityp SEQ gekennzeichnet:

"C64 WIKI 2015"     01 2A  
100 "DATENBANK"        PRG
64  "SPIELE"           SEQ
44  "TOOLS"            REL
56  "ANWENDUNGEN"      USR
450 BLOCKS FREE            

Bis auf die Bezeichnung des Typs im Verzeichnis gelten sämtliche Eigenschaften einer sequenziellen Datei aus Sicht des CBM-DOS ebenso für USR- und PRG-Dateien. Kleine Unterschiede ergeben sich lediglich in der Verwendung.

Eine offene oder nicht korrekt geschlossene Datei wird mit der dafür üblichen Markierung, einem "*" vor dem Typkürzel (Markierung als sogenanntes splat file), gekennzeichnet.

Vor- und Nachteile[Bearbeiten | Quelltext bearbeiten]

Beim Vergleich sequentieller Dateien mit Relativdateien zeigen sich folgende Vor- und Nachteile:

Vorteile:

  • Effiziente Speicherausnutzung auf Diskette (geringer Anteil organisatorischer Daten).
  • Geringerer Verwaltungsaufwand im DOS, daher können mehr Dateien gleichzeitig geöffnet sein (abhängig vom jeweiligen Laufwerk).
  • Einfache Verwendung unter BASIC.
  • Gut für binäre Daten einsetzbar, da kein Zeichen eine besondere Bedeutung hat und das Dateiende eindeutig gekennzeichnet ist.
  • Als Basisoperation ist das Zusammenfügen (Merge- oder Combine-Funktion des DOS) mehrerer Dateien zu einer einzigen unterstützt.

Nachteile:

  • Es müssen immer alle Daten bis zur gesuchten Position eingelesen (und auch übertragen) werden.
  • Es ist nicht möglich einzelne Bereiche innerhalb der Datei zu ändern.
  • Ein Anhängen von Daten ist zwar möglich, dazu muss aber das DOS zuerst alle vorhergehenden Datenblöcke lesen (wobei die Daten dazu nicht übertragen werden müssen, was dann auch schneller als etwa bei einem Ladevorgang vonstatten geht).

Kenndaten[Bearbeiten | Quelltext bearbeiten]

Kennzahlen einer sequenzielle Datei:

  • Dateilänge: Kann alle auf dem jeweiligen Drive (Laufwerk bei einem Doppellaufwerk) zur Verfügung stehenden Blöcke (bei einer 1541 664 Blöcke) umfassen.
  • Maximale Nutzdatengröße: Blockanzahl * 254 Bytes


Verwendung[Bearbeiten | Quelltext bearbeiten]

Verwendet werden SEQ-Dateien zum Speichern beliebiger Daten, vorzugsweise solche, die sich selten ändern.
In Kombination mit Relativdateien, werden SEQ-Dateien als Index verwendet, um von einem suchbaren Schlüsselwert auf den zugehörigen Dateneintrag (Record). Die Handhabung der Index-Datei ist dabei mit verhältnismäßig geringem Aufwand möglich.

Die Zugriffsart auf die Datei wird beim Öffnen durch ein Suffix und gegebenenfalls Präfix festgelegt:

Zugriffsart Dateiparameter für OPEN-Befehl Bemerkung
Lesen (Read) "DATEINAME,R" Ohne Suffix wird die Datei automatisch zum Lesen geöffnet. Ist die Datei nicht vorhanden, gibt die Floppy auf dem Fehlerkanal "62, FILE NOT FOUND,00,00" aus.
Erstellen/Schreiben (Write) "DATEINAME,W" Datei erstellen und zum Schreiben öffnen. Ist die Datei schon vorhanden, gibt die Floppy auf dem Fehlerkanal "63, FILE EXISTS,00,00" aus.
Daten anhängen (Append) "DATEINAME,A" Datei öffnen und auf das Dateiende positionieren. Ist die Datei nicht vorhanden, gibt die Floppy auf dem Fehlerkanal "62, FILE NOT FOUND,00,00" aus.
Überschreiben (Replace) "@:DATEINAME,W"
"@0:DATEINAME,W"
Datei zum Überschreiben öffnen. Aufgrund des REPLACE-Bugs nicht zu empfehlen, stattdessen lieber die Datei löschen und neu erstellen.
Ohne fehlerhafte Nebenwirkung kann auch die Syntax mit Drive-Angabe (z.B. Drive 0 im Beispiel) verwendet werden.
Dateiwiederherstellung (Modify) "DATEINAME,M" Dient zum Wiederherstellen von Daten aus einer nicht korrekt abgeschlossenen Datei.

Nach dem Öffnen der Datei können Daten entweder mit den BASIC-Befehlen GET# und INPUT# gelesen oder mit PRINT# geschrieben werden.

Eine Besonderheit ist der Modify-Modus. Dieser dient nicht zum Ändern der Daten, sondern zum Einlesen einer nicht korrekt geschlossenen Datei. Dabei gibt es allerdings das Problem, dass der letzte gültige Datenblock einer nicht geschlossenen Datei auf den potentiellen Folgesektor zeigt, dieser aber noch ungültige Daten inklusive Nachfolgeblock enthält. Daher wird bei Verwendung des Modify-Modus immer mindestens ein Datenblock zu viel (günstigstenfalls mit Null-Bytes) eingelesen, unter Umständen könnte das Einlesen sogar in eine Endlosschleife geraten, falls einer der ungültigen Datenblöcke zufällig als Nachfolger einen bereits gelesenen Block referenziert.

Datenorganisation[Bearbeiten | Quelltext bearbeiten]

Organisiert sind die Daten einer sequentiellen Datei in Blöcken zu 256 Byte, wobei die ersten beiden Bytes Spur und Sektor des Nachfolgeblockes enthalten, aber im Fall des letzten Datenblocks Null als Spurnummer und die Anzahl noch gültigen Bytes im Block im zweiten Byte. Die folgenden 254 Bytes enthalten die Nutzdaten. Die Datei ist also als einfach verkettete Liste organisiert, wobei ihr Directory-Eintrag auf den ersten Datenblock zeigt.

Aufbau eines Datenblocks (wenn nicht der letzte):

Position Beschreibung
0 Spurnummer des nächsten Datenblocks
1 Sektornummer des nächsten Datenblocks
2 - 255 Datenbytes

Aufbau letzter Datenblock:

Position Beschreibung
0 0
1 Wert, der die Anzahl der Daten in diesem Block angibt (1-254).
2 - 255 Datenbytes entsprechend der Anzahl gemäß Position 1.


Details zum Directory-Eintrag einer sequentiellen Datei findet sich beim Aufbau des Directorys.


Besonderheiten[Bearbeiten | Quelltext bearbeiten]

Bezugnehmend und verifiziert auf CBM-DOS 2.6, typischerweise auf einem 1541er-Laufwerk.

Leerdatei[Bearbeiten | Quelltext bearbeiten]

Das Anlegen einer Leerdatei mit

OPEN 1,8,2,"0-DATEI,W"
CLOSE 1

gibt beim Auslesen z.B. mit folgendem Programm

1000 OPEN 1,8,3, "0-DATEI"
1010 FOR C=0 TO 1E6
1020 GET#1,A$
1030 PRINT C":"ASC(A$+CHR$(.)),
1040 GET A$:IF ST OR A$<>"" THEN C=C+1E6
1050 NEXT
1060 PRINT: PRINT "ST="ST,C-1E6 "BYTES"
1070 CLOSE 1
1100 OPEN 15,8,15
1110 INPUT#15,E$,F$,T$,S$
1120 PRINT E$","F$","T$","S$
1130 CLOSE 15

folgendes aus (die Byte-Folge mit dezimalem PETSCII-Code):

 0 : 13    1 : 0     2 : 2     3 : 13
ST= 64     4 BYTES
00,OK,00,00

Daraus folgt, dass sich immer das Muster bestehend aus 4 Zeichen: <13> <0> <2> <13> ergibt.
Eine Datei der Länge 0 lässt sich auf diese Art nicht erzeugen.

Dateien der Länge 1[Bearbeiten | Quelltext bearbeiten]

Wie auch bei einer Leerdatei ergibt sich beim Versuch eine Datei mit Länge 1 zu erstellen ein ähnliches Bild:

OPEN 1,8,2,"1-DATEI,W"
PRINT#1, "A";
CLOSE 1

ergibt beim Auslesen (mit obigem Ausleseprogramm) die Byte-Folge:

 0 : 65    1 : 0     2 : 2     3 : 65
ST= 64     4 BYTES
00,OK,00,00

D. h., es ergibt sich immer das Muster bestehend aus 4 Zeichen: <Zeichen> <0> <2> <Zeichen>
Eine Datei der Länge 1 lässt sich auf diese Art nicht erzeugen.

Dateien ab einer Länge von 2 Zeichen[Bearbeiten | Quelltext bearbeiten]

Erst ab einer Anzahl von 2 Zeichen, zeigt sich beim Auslesen der Datei tatsächlich die geschriebenen Daten.

OPEN 1,8,2,"2-DATEI,W"
PRINT#1, "AB";
CLOSE 1

ergibt beim Auslesen (mit obigem Ausleseprogramm) die Byte-Folge:

 0 : 65    1 : 66
ST= 64     2 BYTES
00,OK,00,00

Hier handelt es sich um die Codes der tatsächlich geschriebenen Zeichen.

Beispiel[Bearbeiten | Quelltext bearbeiten]

Zeilenweises Schreiben und Lesen textueller Daten einer sequentiellen Datei namens "TESTDATEI":

100 PRINT CHR$(147)CHR$(14);
105 :   REM SCHREIBEN
110 OPEN 2,8,2,"TESTDATEI,S,W": GOSUB 220
120 PRINT#2,"1 DIES IST EINE SEQUENTIELLE TEXTDATEI,"
130 PRINT#2,"2 DIE AUS DREI ZEILEN BESTEHT."
140 PRINT#2,"3 ENDE."
150 CLOSE 2
155 :   REM LESEN
160 OPEN 2,8,2,"TESTDATEI,S,R": GOSUB 220
170 FOR C=0 TO 1
180 INPUT#2,A$: PRINT A$
190 C=ABS(ST)
200 NEXT
210 CLOSE 2:END
215 :   REM FEHLERKANAL LESEN
220 OPEN 1,8,15
230 INPUT#1,FF,FF$
240 IF FF>0 THEN PRINT FF,FF$
250 CLOSE 1
260 RETURN


Weblinks[Bearbeiten | Quelltext bearbeiten]