Satzorientierte Ein-/Ausgabe, die bei SAM-, ISAM- und PAM-Dateien möglich ist, ist immer eine binäre Ein-/Ausgabe. Daher werden bei satzorientierter Ein-/Ausgabe mit den ASCII- Varianten der Ein-/Ausgabefunktionen (siehe "C-Bibliotheksfunktionen, die ASCII-Codierung unterstützen") Daten weder beim Schreiben, noch beim Lesen konvertiert.
Mit den Funktionen fopen
/fopen64
bzw. freopen
/freopen64
muss die Datei stets im Binärmodus und mit dem Zusatz "type=record" eröffnet werden.
Mit den Funktionen creat
/creat64
bzw. open
/open64
muss die Datei stets im Binärmodus und der Angabe O_RECORD eröffnet werden.
Ein-/Ausgabefunktionen, die Zeichen oder Zeichenketten (bis \n) einlesen oder ausgeben, sind bei satzorientierter Ein-/Ausgabe nicht anwendbar.
Verfügbare Ein-/Ausgabefunktionen
Folgende Funktionen stehen zur Verarbeitung von Dateien mit satzorientierter Ein-/Ausgabe zur Verfügung:
| Öffnen |
| Schließen |
| Lesen |
| Schreiben |
| Positionieren im Datenstrom |
| Position im Datenstrom |
| Positionieren auf Dateianfang/Dateiende |
| Positionieren auf Dateianfang |
| explizit Positionieren in einer ISAM-Datei |
| Löschen eines Satzes in einer ISAM-Datei |
Außerdem sind folgende Funktionen zur Dateiverwaltung bzw. Fehlerbehandlung unverändert anwendbar:
feof
, ferror
, _fnlinserted
, clearerr
, unlink
, remove
, rename
Alle hier nicht aufgeführten Ein-/Ausgabefunktionen stehen für die satzorientierte Ein-/Ausgabe nicht zur Verfügung und werden mit Fehler-Returnwert abgewiesen.
Die beiden Makros getc
und putc
haben jedoch aus Performancegründen keine Prüfung. Das Verhalten ist undefiniert, wenn diese Makros auf Dateien mit satzorientierter Ein-/Ausgabe angewendet werden.
Verarbeitung einer Datei in satz- und stromorientierter Ein-/Ausgabe
Es ist möglich, eine Datei, die mit satzorientierter Ein-/Ausgabe erstellt wurde, für stromorientierte Ein-/Ausgabe zu öffnen und umgekehrt. Es ist jedoch zu beachten, dass bei stromorientierter Ein-/Ausgabe nicht alle Dateiattribute unterstützt werden, die bei satzorientierter Ein-/Ausgabe möglich sind.
FCBTYPE einer neu zu erstellenden Datei
Der FCBTYPE einer neu zu erstellenden Datei kann folgendermaßen festgelegt werden:
Angabe in einem ADD-FILE-LINK-Kommando und Verwendung des LINK-Namens bei den Funktionen
fopen
/fopen64
bzw.freopen
/freopen64
Angabe des
forg
-Parameters bei den Funktionenfopen
/fopen64
bzw.freopen
/freopen64
, und zwar:„forg=seq“: Es wird eine SAM-Datei erstellt
„forg=key“: Es wird eine ISAM-Datei erstellt.
Es gibt folgende Einschränkungen für den FCBTYPE einer Datei und die Angaben bei fopen
/fopen64
bzw. freopen
/freopen64
:
Bei Angabe von "type=record" muss die Datei den FCBTYPE SAM, PAM oder ISAM haben.
Bei Angabe von "forg=seq" muss die Datei den FCBTYPE SAM oder PAM haben.
Bei Angabe von "forg=key" muss die Datei den FCBTYPE ISAM haben.
Die Angabe des Anfügemodus "a" ist für ISAM-Dateien unzulässig. Die Position bestimmt sich aus dem Schlüssel im Satz.
Es gibt folgende Einschränkungen für den FCBTYPE einer Datei und die Angaben bei creat
/creat64
bzw. open
/open64
:
Bei Angabe von O_RECORD muss die Datei den FCBTYPE SAM, PAM oder ISAM haben.
Mehrfachschlüssel bei ISAM-Dateien
Standardmäßig sind für ISAM-Dateien keine Mehrfachschlüssel zugelassen. Durch die Angabe von DUP-KEY=Y in einem ADD-FILE-LINK-Kommando können jedoch Mehrfachschlüssel verwendet werden.
Beispiel für die satzorientierte Verarbeitung einer ISAM-Datei
Folgendes Programm erstellt und verarbeitet eine ISAM-Datei mit satzorientierter Ein-/Ausgabe.
#include <stdio.h> #include <string.h> #include <stdlib.h> main() { FILE * isamfp; size_t ret=0; int i,intret; char puffer[200]; char puffer2[200]; static char * texts[3] = {"1 Ritchie***, 9999, ZZ", "2 Kernighan*, 8765", "3 Stroustrup, 1234, C++"}; static char isamlink[] = "ADD-FILE-LINK LINK=ISAMFILE,F-NAME=DATEI.ISAM," "ACCESS-METHOD=ISAM(KEY-LEN=10,KEY-POS=4)," "REC-FORM=FIXED(REC-SIZE=50)"; static int maxtext = 3; fpos_t isampos; ret = system(isamlink); if (ret != 0) { printf("system(isamlink) fehlerhaft\n"); exit(1); } isamfp = fopen("link=isamfile", "wb+,type=record,forg=key"); if (isamfp == 0) { printf("Das Oeffnen von isamfp ist nicht gelungen\n"); exit(2); } /* 3 Saetze in ISAM-Datei schreiben */ for (i=0; i<maxtext; i++) { ret = fwrite(texts[i], 1, strlen(texts[i]), isamfp); if (ret == 0) { printf("Fehler beim ISAM-Schreiben\n"); exit(3); } } /* Saetze ab Dateibeginn lesen und auf Standardausgabe schreiben */ rewind(isamfp); for (i=0; i<maxtext; i++) { ret = fread(puffer, 1, 100, isamfp); fwrite(puffer, 1, ret, stdout); } /* Explizit auf Grund des Schluesselwerts positionieren und verarbeiten */ flocate(isamfp, "Ritch", strlen("Ritch"), _KEY_GE); ret = fread(puffer, 1, 100, isamfp); /*"Ritchie" ist gelesen */ *(puffer+ret) = '\0'; /* EOS am Ende des Satzes */ printf("\nGelesener Satz: %s\n", puffer); fgetpos(isamfp, &isampos); /* Position hinter gelesenem */ /* Satz merken */ ret = fread(puffer, 1, 100, isamfp); /*"Stroustrup" ist gelesen */ *(puffer+ret) = '\0'; /* EOS am Ende des Satzes */ printf("Gelesener Satz: %s\n", puffer); fsetpos(isamfp, &isampos); /* Zurueckpositionieren */ ret = fread(puffer2, 1, 100, isamfp); /*"Stroustrup"ist erneut gelesen*/ *(puffer2+ret) = '\0'; /* EOS am Ende des Satzes */ printf("Gelesener Satz: %s\n", puffer2); intret = fdelrec(isamfp, "Kernighan*"); /* einen Satz loeschen */ if (intret == 0) printf("Kernighan geloescht\n"); intret = fdelrec(isamfp, "Kernighan*"); /* Versuch, bereits geloeschten */ if (intret > 0) /* Satz zu loeschen */ printf("OK, dieser Satz existiert nicht mehr\n"); else printf("Fehler, \"Kernighan*\" koennte man zweimal loeschen\n"); printf("******* PROGRAMM ENDE *******\n"); }