APPLICATIONSDISQUE ★ BUECHERDATEI|CPC MAGAZIN) ★

Buecherdatei (CPC Magazin)Applications Disque
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

In der letzten Folge haben wir einen Ausflug in die Innenwelt der Diskette gewagt und mit Hilfe des DMONs den Aufbau der Diskette genauer untersucht. Heute kehren wir zurück zur Praxis und wollen ein Dateiprogramm entwickeln. Als Datenspeicher dienen die Sektoren der Diskette.

Sektoren als Speicher

Mit der Befehlserweiterung DISCRSX (siehe CPC Magazin 3/86) ist es möglich, auf einen beliebigen Sektor der Diskette zuzugreifen. Sowohl theoretisch als auch praktisch könnèn 360 Sektoren zu je 512 Bytes mit beliebigen Daten gefüllt werden. Solange der Programmierer selbst für die Organisation der Daten Sorge trägt, ist es vollkommen egal, wo die Daten abgelegt werden. Wichtig ist nur, daß zusammengehörige Informationen auf der Diskette auch wiedergefunden werden können.

Nehmen wir als Beispiel an, daß alle Sektoren einer Diskette als Datenspeicher dienen und ein Datensatz eine Länge von 512 Zeichen besitzt. Daraus folgt, daß die Diskette 360 Datensätze zu je 512 Zeichen aufnehmen kann. Numerieren wir die Datensätze von 0 bis 359 durch, so ist eine Zuordnung zwischen Datensatznummer und Sektor sehr einfach möglich: Der Datensatz mit der Nummer 0 liegt im ersten Sektor (0) der Diskette, Datensatz Nummer 1 im zweiten (1) etc. Es ist jetzt nur noch eine Umrechnung der Sektomummer in Spur und Sektor notwendig:

Spur = INT (DSnummer/9)
Sektor = DSnummer MOD 9

(Die MODulo-Funktion gibt den ganzzahligen Rest einer Division wieder.) Nehmen wir dazu ein kurzes Zahlenbeispiel. Gesucht wird der Datensatz Nummer 11:

INT (11/9) = 1 (Spur)
11 MOD 9 = 2 (Sektor)

D. h., der Datensatz 11 liegt in Spur 1/ Sektor 2. Mit den Befehlen SECREAD und SECWRITE der Befehlserweiterung kann der Sektor gelesen oder beschrieben werden. Beim Lesen werden alle Bytes des Sektors in den Datenpuffer einiesen, beim Schreiben werden alle
Bytes des Puffers in den entsprechenden Sektor geschrieben. Die Daten des Puffers müssen entsprechend aufbereitet sein (Datenfelder, siehe Folge 2). In der Regel liegen die Informationen als ASCII-Zeichenwerte vor. Die Informationen des Puffers müssen für die weitere Beschreibung (z. B. Anzeige) Strings zugeordnet werden:

1 FOR i = 0 TO 99
2 feld 1 $ = feld1$ + CHR$(PEEK (pufferadr + i))
3 NEXT i

Das Beispiel liest die ersten 100 Zeichen (ASCII-Werte) des Datensatzes (Puffer) in die Stringvariable feld1$. So können auch die restlichen Daten des Puffers an Strings (hier Datenfelder) zugewiesen werden. Nun können wir mit den Informationen wie gewohnt arbeiten. '

Das Füllen des Datenpuffers ist ähnlich einfach. Die Inhalte der Datenfelder (Strings) werden als ASCII-Zeichen-werte in den Datenpuffer gelegt;

1 FOR i = 0 TO 99
2 POKE pufferadr + i, ASC (MID$(feld1$, i + 1,1))
3 NEXT i

Ist so der gesamte Puffer mit den Informationen gefüllt, kann er in einen beliebigen Sektor der Diskette gespeichert werden. Das Verfahren ist denkbar einfach und unproblematisch, wenn folgende Punkte berücksichtigt werden:

  1. Der Aufbau der Datensätze muß immer gleich sein. D. h., die einzelnen Datenfelder müssen immer an derselben Position beginnen. Dadurch ist gewährleistet, daß jedes Datenfeld auch wieder richtig eingelesen werden kann. Der Programmierer muß eine genaue Vorstellung über den Aufbau des Datensatzes haben. Beispiel für einen Datensatzaufbau:

    Feld1 = 100 Zeichen Feld 2 = 20 Zeichen Feld 3 = 8 Zeichen

  2. Jedes Datenfeld muß eine vorher definierte Anzahl von Zeichen (Stellen) besitzen. Hat die Information, die in einem Datenfeld gespeichert werden soll, weniger als die vereinbarte Zeichenanzahl, ist es mit Leerzeichen (o.a.) aufzufüllen. Es darf natürlich auch nicht länger sein.

Prüfung ob zu lang:

IF LEN (feld1$) >100 THEN feld1$ = LEN (feld1$, 100)

Datenfeld mit SPACE auffüllen: feld$l = feld1$ + SPACE$

(100-LEN (feld1$))

Aufteilung eines Sektors

Bei unseren bisherigen Betrachtungen mußte ein Datensatz immer genau 512 Zeichen groß sein. In der Praxis können aber fast beliebig große Datensätze Vorkommen. Es gibt zwei Verwaltungsmöglichkeiten, die sich in der Programmierung und Verwaltung erheblich unterscheiden.

Die erste Variante ist recht einfach zu verstehen und der Programmieraufwand ist noch recht gering. Sie geht davon aus, daß ein Datensatz immer komplett in einem Sektor liegt. Daraus folgt, daß ein Sektor folgende Datensätze enthalten kann:

1 Datensatz mit 512 Zeichen
2 Datensätze mit 256 Zeichen
4 Datensätze mit 128 Zeichen
8 Datensätze mit 64 Zeichen
16 Datensätze mit 32 Zeichen

512 Datensätze mit 1 Zeichen

Es gibt aber zwei gravierende Nachteile an diesem Verfahren:

  1. 1. Ist die von Ihnen gewählte Daten-satzgröße z.B. 65 Zeichen, so muß eine Datensatzgröße von 128 Zeichen gewählt werden! Man verschenkt also unter Umständen eine ganze Menge Speicherplatz.
  2. Die maximale Datensatzgröße ist auf 512 Zeichen begrenzt.

Dafür ist aber der Zugriff auf die Sektoren sehr einfach zu lösen. Verdeutlichen wir uns das an einem Zahlenbeispiel: Es wurde eine Datensatzlänge (DSlänge) von 64 Zeichen gewählt. Dann passen 8 Datensätze in einen Sektor:

anzahl = 512/DSlänge
8 = 512/64

Suchen wollen wir den Datensatz Nummer 20 (DSnummer). Der Datensatz befindet sich dann im Sektor mit der Nummer 2 (dritter Sektor):

SKnummer = INT (DSnummer/anzahl)
2 = INT (20/8)

Jetzt muß die Sektornummer in Spur und Sektor umgerechnet werden:

Spur = INT (SKnummer/9)
0 = INT (2/9)
Sektor = SKnummer MOD 9 2 = 2 MOD 9

Nun wissen wir, daß der Datensatz in Spur 0/Sektor 2 zu finden ist. Er kann nun in den Rechner geladen werden. Doch wir können sogar noch errechnen, an welcher Position der Datensatz im Sektor (bzw. Puffer) beginnt:

Posi = (DSnummer MOD anzahl) * DSlänge
256 = (20 MOD 8) * 64

Der Datensatz beginnt ab Byte 256 im Sektor (Puffer).

Sie sehen, daß das Ermitteln der Daten noch recht einfach ist. Etwas aufwendiger ist es schon beim folgenden Verfahren, dafür ist es aber sehr viel flexibler.

Relative Organisation

Stellen Sie sich zunächst einmal alle Sektoren der Diskette wie eine Aneinanderreihung von Speicherblöcken vor. Sie beginnt mit Sektor 359. Es werden Datensätze mit einer Länge von jeweils 200 Zeichen immer direkt hintereinander abgelegt. (Kein einziges Byte wird verschenkt.) Dann liegt Datensatz 0 von 0 bis 199, Datensatz 1 von 200 bis 399, Datensatz 2 von 400 bis 599 usw.

Bei unserem Beispiel passen die ersten beiden Datensätze noch in den ersten (0.) Sektor, der Datensatz 2 hingegen beginnt in Sektor 0 und endet in Sektor 1. Er überlappt also zwei Sektoren. Um auf den Datensatz 2 zugreifen zu
können, muß sowohl der Sektor 0 als auch der Sektor 1 in den Rechner eingelesen werden. Je größer ein Datensatz ist, auf desto mehr Sektoren kann er ver-teüt sein.

Damit auf jeden Datensatz zugegriffen werden kann, müssen folgende Daten ermittelt werden:

  1. In welchem Sektor beginnt der Datensatz?
  2. Wo beginnt der Datensatz im Sektor?
  3. Ist eine Überlappung vorhanden?
  4. Wenn ja, über wieviele Sektoren?
  5. Alle Sektoren, die Teile vom Datensatz enthalten, müssen zur weiteren Bearbeitung in den Rechner geladen werden.

Doch immer der Reihe nach. Als erstes ermitteln wir die Sektomummer, wo der Datensatz beginnt:

SKnummer = INT (DSnummer * DSlänge/512)
0 = INT (2 *200/512)

Der Datensatz beginnt innerhalb des Sektors im Byte 400:

Posi = (DSnummer * DSlänge) MOD 512 400 = 2 * 200 MOD 512 Jetzt muß festgestellt werden, ob ein Überhang in den nächsten Sektoren vorhanden ist:

IF (512 - Posi) < DSlänge THEN... Überhang!
(512 - 400) < 200... Überhang!

Ein Überhang ist immer vorhanden, wenn der Vergleich zutrifft. Bei unserem Beispiel ist ein Überhang vorhanden (112 ist kleiner als 200). Deshalb müssen wir feststellen, in wievielen folgenden Sektoren der Datensatz noch voll enthalten ist:

Folge = INT ((DSlänge - 512 + Posi)/ 512)
0 = INT ((200 - 512 + 400)/512)

Das Ergebnis besagt, daß der Datensatz den folgenden Sektor nicht voll ausfüllt (0). D.h., der gesuchte Datensatz belegt nur einen Teü des folgendes Sektors (ein Überhang ist ja vorhanden)!

Mit diesen Daten können wir auch die Anzahl der Zeichen (Überhang in den nächsten Sektor) ermitteln, die sich vom Datensatz im folgenden Sektor befinden:

Anzahl = (DSnummer + 1) * DSlänge MOD 512 - 1

87 = (2 + 1) * 200 MOD 512 - 1 Ist die errechnete Anzahl = 0, so endet der Datensatz genau mit dem Sektorenende. Hier liegen aber die letzten 88 Zeichen (0 - 87) im folgenden Sektor. Jetzt haben wir alle notwendigen Informationen: Wir wissen, wo der Datensatz beginnt (SKnummer), in wieviel folgenden Sektoren der Datensatz vorhanden ist (Folge und Überhang). Alle Sektoren, in denen der Datensatz hegt, müssen nun in den Rechner geladen werden. Jeder Sektor kommt dabei in einen anderen Puffer (vorher noch die DSnummer in Spur und Sektor umrechnen, siehe weiter oben). Es bietet sich an, die Sektoren hintereinander in den Rechner zu laden z.B.:

Adresse 30000 - 30511 (erster Sektor) Adresse 30512-31023 (zweiterSektor) etc.

Da wir die Startposition (Posi) des Datensatzes errechnet haben, wissen wir auch genau, wo der Datensatz im Puffer (in den Puffern) liegt:

Anfang = Pufferanfang + Posi 30400 = 30000 + 400

Und das Ende ist ebenso eindeutig:

Ende = Anfang + DSlänge - 1 30599 = 30400 + 200-1

Die Daten des Datensatzes können wie bereits oben beschrieben auf den Puffer einer String-Variablen zugewiesen werden. Das Beschreiben eines Datensatzes ist analog: Ermitteln, wo der Datensatz gespeichert wird, den/die entsprechenden Sektor(en) einiesen, Puffer an den richtigen Stellen mit den Daten füllen und alle Sektoren wieder zurückschreiben.

Das hier beschriebene Verfahren ist nicht ganz einfach zu verstehen. Es sollte auch zunächst nur den logischen Zusammenhang verdeutlichen. In der Praxis geht man sicherlich einen einfacheren Weg.

  1. Ermitteln, in welchem Sektor der Datensatz beginnt. Dann feststellen, an welcher Position er im Sektor anfängt (SKnummer und Posi).
  2. Ermitteln, in welchem Sektor der folgende Datensatz (DSnummer + 1) beginnt.
  3. Einlesen aller Sektoren vom ersten Sektor bis zum Sektor, wo der nächste Datensatz beginnt.

Nun sind alle Informationen im Puffer. Der gesuchte Datensatz beginnt in der Adresse: DSbegin = Pufferadresse + Posi und endet in: DSende = DSbegin -DSlänge - 1. Rechnen Sie einfach mal ein paar Zahlenbeispiele durch und machen Sie sich ein paar Speicherskizzen. Das hilft bestimmt.

Beide Verfahren sind für die Arbeit mit Direktzugriffsdateien sehr wichtig. Je nach Anwendungsfall sollten Sie sich entscheiden, welches die geeignetere Form ist. Wenn Sie eine Datei mit einer festen Datensatzlänge von 128 Zeichen haben, so bietet sich natürlich das erste Verfahren an. Immer dann, wenn es sich aber um flexible Längen handelt (z.B. Datenbank), müssen Sie auf die zweite Variante zurückgreifen.

Um die heutige Folge abzurunden, bringen wir zur Entspannung noch ein Anwendungsbeispiel. Es ist eine Bücherdatei für 700 Titel. Jeder Datensatz ist 255 Zeichen lang und besteht aus 10 Datenfeldern. Die Datei wird auf einer (leeren) Diskette verwaltet, die im DATEN-Format (FORMAT D) formatiert wurde. Gleichzeitig arbeitet das Programm mit einer INDEX-Datei, die separat auf einer anderen Diskette angelegt und gespeichert wird (z. B. auf der Programmdiskette). Das Programm ist für Sie wieder nur eine Anregung (machen
Sie es besser!!). Vergessen Sie nicht, die Befehlserweiterung DISCRSX aus der 4. Folge zu MERGEn (ab Zeüe 60000).

Beim nächsten Mal gehen wir auf die Bücherdatei ein und behandeln das Thema der Index-Dateien (ISAM).

Manfred Walter Thoma , CPC Magazin

★ PUBLISHER: CPC Magazin
★ YEAR: 1986
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LICENCE: LISTING
★ AUTHOR: Manfred Walter Thoma

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
  » Buecherdatei    (CPC  Magazin)    GERMANDATE: 2020-05-19
DL: 6 fois
TYPE: ZIP
SIZE: 8Ko
NOTE: 40 Cyls
.HFE: NON

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » RSX Basic-Erweiterung v1.0 (CPC Amstrad International)
» Applications » Coding - Hisoft - Nevada Cobol
» Applications » Coding - Jrt - Pascal (CPC Amstrad International)
» Applications » Compilateur Intègral
» Applications » CPC+200
» Applications » Doubleur (Tilt)

QUE DIT LA LOI FRANÇAISE:

L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!

CPCrulez[Content Management System] v8.7-desktop
Page créée en 465 millisecondes et consultée 20 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.