|
Das nachfolgende C/C++ Beispiel demonstriert die Verwendung der von FATS bereitgestellten  Index-Befehle:
"C" Create Indexfile (Indexdatei definieren, erstellen und öffnen.) | |
"O" Open Indexfile (Indexdatei öffnen.) | |
"K" Close Indexfile (Eine oder alle Indexdateien schließen.) | |
"I" Insert Record ((Haupt)-Schlüssel in Indexdatei einfügen und Datensatznummer besetzen.) | |
"F" Search First (Suchen des ersten Schlüssels.) | |
"L" Search Last (Suchen des letzten Schlüssels.) | |
"N" Search Next (Suchen des nächsten Schlüssels in Folge.) | |
"A" Search Next After (Suchen des auf den angegebenen Schlüssel folgenden Schlüssels.) | |
"E" Search Previous Before (Suchen des dem angegebenen Schlüssel vorangehenden Schlüssels.) | |
"Y" Auto Refresh (Bestimmt das Verhalten der Bibliothek im Netzwerk- und Einzelplatzbetrieb.) |
/* FATS 02.30 (c) GCS Software, Udo Gertz 1993-1998 Testprogramm (Turbo C, Borland C/C++) Erstellen der Testdateien KUNDEN.DAT / KUNDEN.KEY 19-03-2009 U.Gertz */ #include <stdio.h> #include <io.h> #include <fcntl.h> #include <sys\types.h> #include <sys\stat.h> #include <stdlib.h> #include <string.h> #include <mem.h> #include "FATS.h" /* Benötigte Objekt-Dateien ======================== Folgende Objekt-Module werden benötigt, wenn FATS zum Anwendungsprogramm gelinkt werden soll: FATS.OBJ Universalmodul FATS_TCS.OBJ Schnittstelle / Small-Modell FATS_TCM.OBJ Schnittstelle / Medium-Modell FATS_TCC.OBJ Schnittstelle / Compact-Modell FATS_TCL.OBJ Schnittstelle / Large-Modell Wenn Sie die FATS Workstation Engine verwenden möchten, dann benutzen Sie eine der folgenden Bibliotheken: FATSTCSR.LIB Schnittstelle / Small-Modell FATSTCMR.LIB Schnittstelle / Medium-Modell FATSTCCR.LIB Schnittstelle / Compact-Modell FATSTCLR.LIB Schnittstelle / Large-Modell Wenn Sie die erweiterte Version von FATS erworben haben (FATSXWE.EXE), dann müssen Sie eine der Bibliotheken FATSXCSR.LIB (Small), FATSXCMR.LIB (Medium), FATSXCCR.LIB (Compact) oder FATSXCLR.LIB (Large) verwenden. Compilieren der Programme ========================= Um Ihre Programme zu übersetzen ist eine der folgenden Methoden zu wählen: 1. Methode: FATS an das Anwendungsprogramm binden BCC -m[?] TST1_GER.C FATS_TC[?].OBJ FATS.OBJ [?] == s (Small Modell), m (Medium), c (Compact), l (Large) 2. Methode: Aufruf der Workstation Engine (FATS_WE.EXE) BCC -m[?] TST1_GER.C FATSTC[?]R.LIB oder wenn Sie die erweiterte Version von FATS besitzen: (FATSXWE.EXE) BCC -m[?] TST1_GER.C FATSXC[?]R.LIB FATS Befehle ausführen ====================== Alle FATS Befehle werden mit einer Funktion ausgeführt: unsigned long FATSCALL(char *szCmnd, unsigned short *uFATSError, char *szReturnKey); Bedeutung der verwendeten Parameter: szCmnd Dieser String definiert den auszuführenden FATS- Befehl sowie die dazugehörenden Parameter. nErrorcode Über diese Variable wird die Anwendung über Erfolg (0) oder Mißerfolg (<> 0) der letzten FATS-Aktion unterrichtet. szReturnKey Ein gefundener Schlüssel wird in diesem String gespeichert. Rückgabewert: Datensatznummer */ struct kdat { char LOESCHKENNZ; char ANREDE[6]; char NAME[26]; char BRANCHE[26]; char STRASSE[26]; char PLZ[6]; char ORT[21]; }; char szCmnd[256]; char szFATSkey[256]; unsigned short uFATSError; unsigned long dwFATSRecno; struct kdat kdata; main () { char cChar; int hKunden; int hDemodata; int nCount = 0; int nIOresult; printf("\nDieses Programm muß mit Turbo- / Borland-C übersetzt werden.\n\n"); printf("Folgende Objektmodule benötigen Sie:\n\n"); printf("Small-Model:\tFATS.OBJ & FATS_TCS.OBJ\n"); printf("Medium-Model:\tFATS.OBJ & FATS_TCM.OBJ\n"); printf("Compact-Model:\tFATS.OBJ & FATS_TCC.OBJ\n"); printf("Large-Model:\tFATS.OBJ & FATS_TCL.OBJ\n\n"); printf("Bitte [ENTER] drücken...\n"); cChar=getchar(); /* -------> Aktivierung des Netzwerkbetriebes "Y" Auto Refresh Kommando FATS ist standardmäßig für den Betrieb im Netzwerk ausgestattet. Beinahe alle Befehle können sowohl im Einzelplatz- als auch im Netzwerkbetrieb ausgeführt werden. Standardmäßig sind die Netzfunktionen ausgeschaltet. Sie können diese mit dem Befehl "Y\2" initialisieren. Diese Initialisierung wird normalerweise beim Programmstart erledigt und gilt dann für die gesamte Laufzeit des Programmes. */ // dwFATSRecno = FATSCALL( "Y\\2", &uFATSError, szFATSkey ); /* -------> ASCII-Datei mit Demodaten öffnen */ hDemodata = open( "..\\..\\..\\DEMODATA\\KUNDEN.ASC", O_BINARY|O_RDONLY ); /* -------> Datendatei erstellen */ printf("Datendatei wird erstellt ...\n"); hKunden = creat( "KUNDEN.DAT", S_IREAD|S_IWRITE ); setmode(hKunden, O_BINARY); /* -------> Indexdatei erstellen */ /* "C" Create Indexfile Mit diesem Befehl erstellen Sie eine Indexdatei, wobei eine eventuell bereits vorhandene Datei mit demselben Dateinamen gelöscht wird. Die Indexdatei wird dabei gleichzeitig mit den über den Befehl Auto Refresh (Y) definierten Öffnungsflags geöffnet und der Dateinummer "FileNo" zugewiesen. Diese Nummer muß bei allen nachfolgenden FATS-Befehlen angegeben werden, um mit der Indexdatei zu arbeiten. Maximal 200 Schlüssel pro Datensatz können in einer Indexdatei verwaltet werden, wobei die maximale Schlüssellänge 240 Zeichen beträgt. Beachten Sie bei der Dateipfadangabe, daß der Backslash (\) von FATS als Trennzeichen behandelt wird und daher im Pfad durch einen normalen Schrägstrich ersetzt werden sollte. Alternativ dazu können Sie auch das Trennzeichen umdefinieren, indem Sie dieses als erstes Zeichen im Befehlsstring angeben, z.B. szCmnd = "&C&C:\ARTIKEL.KEY&1&1&A&1" (das Trennzeichen muß ein ASCII-Zeichen kleiner als 48 sein). Der Aufbau des Kommandostrings: szCmnd = "C\{Filename}\{KeyLength}\{KeyCount}\{KeyType}\{FileNo}" FileName Name der Datei, eventuell mit Pfadangabe (z.B. C:/DATEN/ARTIKEL.KEY oder ARTIKEL.KEY) KeyLength Maximale Länge der Schlüssel KeyCount Anzahl Schlüssel (1-200) KeyType Art der Schlüssel (A=ASCII Textschlüssel, I=Integer) FileNo Nummer der Indexdatei (1-40) */ printf( "Indexdatei wird erstellt ...\n\n" ); dwFATSRecno = FATSCALL( "C\\KUNDEN.KEY\\25\\3\\A\\1", &uFATSError, szFATSkey ); /* ======================================================================== Datensätze einfügen ======================================================================== */ printf( "Es werden jetzt 222 Datensätze in die Datei eingefügt. Für jeden\n" ); printf( "Datensatz werden 3 Schlüssel in die Indexdatei eingefügt.\n" ); printf( "Bitte [ENTER] drücken...\n" ); cChar = getchar(); memset( &kdata, 0, sizeof( kdata ) ); do { nIOresult = read( hDemodata, &kdata.ANREDE, 5 ); nIOresult = read( hDemodata, &kdata.NAME, 25 ); nIOresult = read( hDemodata, &kdata.BRANCHE, 25 ); nIOresult = read( hDemodata, &kdata.STRASSE, 25 ); nIOresult = read( hDemodata, &kdata.PLZ, 5 ); if ( read( hDemodata, &kdata.ORT, 20 ) == 20 ) { /* "I" Insert Record Diesem Befehl wird die im "Create Indexfile"-Befehl angegebene Anzahl Schlüssel im Kommandostring übergeben. Die Schlüssel werden in die Indexdatei einsortiert und einer Satznummer zugeordnet, welche in der "RECNO" Variable an das Anwenderprogramm zurückgegeben wird. Anschließend sollte das aufrufende Programm den zugehörigen Datensatz entsprechend der zurückgegebenen Satznummer in die Datendatei speichern. Die Länge der übergebenen Schlüssel darf die beim "Create-Indexfile" angegebene Länge nicht überschreiten, kürzere Schlüssel werden mit dem ASCII-Zeichen 00h auf die maximale Schlüssellänge erweitert. Der Aufbau des Kommandostrings: szCmnd = "I\{FileNo}\{KeyStr1}[\{KeyStr2}[\{KeyStr3}]]" FileNo Nummer der Indexdatei KeyStr# Schlüssel */ sprintf( szCmnd, "I\\1\\%s\\%s\\%s%s", kdata.NAME, kdata.BRANCHE, kdata.PLZ, kdata.ORT ); dwFATSRecno = FATSCALL( szCmnd, &uFATSError, szFATSkey ); if ( uFATSError == 0 ) { printf( "%s --> Satznummer %lu\n", kdata.NAME, dwFATSRecno ); lseek( hKunden, (dwFATSRecno - 1) * sizeof(kdata), SEEK_SET ); nIOresult = write( hKunden, &kdata, sizeof(kdata) ); } } nCount++; } while ( ( nCount < 222 ) && ( uFATSError == 0 ) ); close( hDemodata ); /* "K" Close Indexfile Mit diesem Befehl schließen Sie die über "FileNo" angegebene Indexdatei. Wenn Sie den Datencache mit dem Befehl Auto Refresh (Y) aktiviert haben, dann werden eventuell noch im Cachepuffer befindliche Daten automatisch auf die Platte geschrieben, was Sie jedoch auch jederzeit mit dem Befehl Write Page Map (W) erzwingen können. Wenn der Datencache inaktiv ist, dann werden nach jedem FATS-Befehl sämtliche veränderten Daten auf die Platte geschrieben. Das Schließen der Dateien ist daher nur vor dem Beenden des aufrufenden Programmes notwendig. Wenn Sie den Parameter "FileNo" weglassen, dann werden alle geöffneten Indexdateien geschlossen. Diese Variante empfiehlt sich vor der Beendigung des Anwendungsprogrammes. Der Aufbau des Kommandostrings: szCmnd = "K\{FileNo}" FileNo Nummer der Indexdatei */ dwFATSRecno = FATSCALL( "K\\1", &uFATSError, szFATSkey ); /* ======================================================================== Suche im Index ======================================================================== */ /* "O" Open Indexfile Mit diesem Befehl wird die über "FileName" bestimmte Indexdatei mit den über den Befehl Auto Refresh (Y) definierten Öffnungsflags geöffnet und der Dateinummer "FileNo" zugewiesen. Diese Nummer muß bei allen nach- folgenden FATS-Befehlen angegeben werden, um mit der Indexdatei zu arbeiten. Eine eventuell mit der gleichen Dateinummer bereits geöffnete Indexdatei wird zuvor geschlossen. Beachten Sie bei der Dateipfadangabe, daß der Backslash (\) von FATS als Trennzeichen behandelt wird und daher im Pfad durch einen normalen Schrägstrich ersetzt werden sollte. Alternativ dazu können Sie auch das Trennzeichen umdefinieren, indem Sie dieses als erstes Zeichen im Befehlsstring angeben, z.B. szCmnd = "&O&C:\ARTIKEL.KEY&1" (das Trennzeichen muß ein ASCII-Zeichen kleiner als 48 sein). Der Aufbau des Kommandostrings: szCmnd = "O\{FileName}\{FileNo}" FileName Name der Datei, eventuell mit Pfadangabe (z.B. C:/DATEN/ARTIKEL.KEY oder ARTIKEL.KEY) FileNo Nummer der Indexdatei */ dwFATSRecno = FATSCALL( "O\\KUNDEN.KEY\\1", &uFATSError, szFATSkey ); /* -------> Datensätze nach Name sortiert ausgeben */ printf( "\n\n" ); printf( "Die Datensätze werden jetzt anhand des ersten Schlüssels (NAME)\n" ); printf( "aufsteigend sortiert ausgegeben. Der dabei verwendete FATS-Befehl\n" ); printf( "SEARCH NEXT AFTER kann im Einzelplatz und im Netzwerk verwendet\n" ); printf( "werden.\n" ); printf( "\nBitte [ENTER] drücken...\n" ); cChar = getchar(); /* "F" Search First Dieser Befehl gibt die Datensatznummer und den Schlüsselwert des kleinsten Schlüssels der angegebenen Schlüsselnummer zurück. Der Aufbau des Kommandostrings: szCmnd = "F\{KeyNo}\{FileNo}" KeyNo Schlüsselnummer FileNo Nummer der Indexdatei */ strcpy(szCmnd, "F\\1\\1"); do { dwFATSRecno = FATSCALL( szCmnd, &uFATSError, szFATSkey ); if ( uFATSError == 0 ) { lseek( hKunden, (dwFATSRecno - 1) * sizeof(kdata), SEEK_SET ); if ( read( hKunden, &kdata, sizeof( kdata ) ) == sizeof( kdata ) ) { printf( "%s --> Satznummer %lu\n", kdata.NAME, dwFATSRecno ); } /* "A" Search Next After Dieser Befehl sucht den über "KeyString" und "RecNo" spezifizierten Schlüssel in der Indexdatei und blättert dann um eine Position weiter. Als Ergebnis wird der auf den angegebenen Schlüssel folgende Schlüssel zurückgegeben. Der Aufruf entspricht daher den Befehlen Search Generic (G) mit anschließendem Search Next (N). Im Gegensatz zum Befehl "Search Next" kann dieser Befehl auch problemlos im Netzwerk verwendet werden. Der Aufbau des Kommandostrings: szCmnd = "A\{KeyNo}\{RecNo}\{FileNo}\{KeyString}" KeyNo Schlüsselnummer RecNo Datensatznummer FileNo Nummer der Indexdatei KeyString Schlüssel */ sprintf( szCmnd, "A\\1\\%lu\\1\\%s", dwFATSRecno, szFATSkey ); } } while ( uFATSError == 0 ); /* --------> Datensätze nach Branche sortiert ausgeben */ printf( "\n\n" ); printf( "Die Datensätze werden jetzt anhand des zweiten Schlüssels (BRANCHE)\n" ); printf( "aufsteigend sortiert ausgegeben.\n" ); printf( "Bitte [ENTER] drücken...\n" ); cChar = getchar(); strcpy( szCmnd, "F\\2\\1" ); do { dwFATSRecno = FATSCALL( szCmnd, &uFATSError, szFATSkey ); if ( uFATSError == 0 ) { lseek( hKunden, (dwFATSRecno - 1) * sizeof(kdata), SEEK_SET ); if ( read(hKunden, &kdata, sizeof(kdata)) == sizeof(kdata) ) { printf( "%s %s --> Satznummer %lu\n", kdata.BRANCHE, kdata.NAME, dwFATSRecno ); } /* "N" Search Next Dieser Befehl gibt die Datensatznummer und den Schlüsselwert des nächsten Schlüssels zurück. Ausgegangen wird dabei vom Ergebnis des letzten Suchbefehls, d.h. unmittelbar vor der Anwendung dieses Befehls muß ein beliebiger Such-Befehl, ausgeführt worden sein. Jede Veränderung der Indexdatei durch das Einfügen oder Löschen von Schlüsseln macht einen für diesen Befehl notwendigen internen Zeiger ungültig, wodurch der Next-Befehl fehlschlägt. Da dies im Netzwerk auch von einer anderen Station aus passieren kann, sollte in Netzwerkumgebungen der Befehl Search Next After (A) verwendet werden. Wenn es keinen nächsten Schlüssel gibt, d.h. der zuletzt gefundene Schlüssel der Letzte in Folge war, wird der Fehlercode #15 zurückgegeben. Der Aufbau des Kommandostrings: szCmnd = "N\{FileNo}" FileNo Nummer der Indexdatei */ strcpy(szCmnd, "N\\1"); } } while ( uFATSError == 0 ); /* --------> Datensätze nach PLZ & Ort sortiert ausgeben */ printf( "\n\n" ); printf( "Die Datensätze werden jetzt anhand des dritten Schlüssels (PLZ/ORT)\n" ); printf( "absteigend sortiert ausgegeben.\n" ); printf( "Bitte [ENTER] drücken...\n" ); cChar = getchar(); /* "L" Search Last Dieser Befehl gibt die Datensatznummer und den Schlüsselwert des größten Schlüssels der angegebenen Schlüsselnummer zurück. Der Aufbau des Kommandostrings: szCmnd = "L\{KeyNo}\{FileNo}" KeyNo Schlüsselnummer FileNo Nummer der Indexdatei */ strcpy( szCmnd, "L\\3\\1" ); do { dwFATSRecno = FATSCALL( szCmnd, &uFATSError, szFATSkey ); if ( uFATSError == 0 ) { lseek( hKunden, (dwFATSRecno - 1) * sizeof(kdata), SEEK_SET ); if ( read( hKunden, &kdata, sizeof(kdata)) == sizeof(kdata) ) { printf( "%s %s %s --> Satznummer %lu\n", kdata.PLZ, kdata.ORT, kdata.NAME, dwFATSRecno ); } /* "E" Search Previous Before Dieser Befehl sucht den über "KeyString" und "RecNo" spezifizierten Schlüssel in der Indexdatei und blättert dann um eine Position zurück. Als Ergebnis wird der dem angegebenen Schlüssel vorangehende Schlüssel zurückgegeben. Der Aufruf entspricht daher den Befehlen "Search Generic" mit anschließendem "Search Prev". Im Gegensatz zum Befehl "Search Previous" kann dieser Befehl auch problemlos im Netzwerk verwendet werden. Der Aufbau des Kommandostrings: szCmnd = "E\{KeyNo}\{RecNo}\{FileNo}\{KeyString}" KeyNo Schlüsselnummer RecNo Datensatznummer FileNo Nummer der Indexdatei KeyString Schlüssel */ sprintf( szCmnd, "E\\3\\%lu\\1\\%s", dwFATSRecno, szFATSkey ); } } while ( uFATSError == 0 ); /* --------> Indexdatei schließen */ dwFATSRecno = FATSCALL( "K\\1", &uFATSError, szFATSkey ); close( hKunden ); }
© 2008 GCS Software, Udo Gertz