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/fopen64bzw.freopen/freopen64Angabe des
forg-Parameters bei den Funktionenfopen/fopen64bzw.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");
}