|
Textdateien spielen im Zusammenhang mit der CGI-Programmierung eine große Rolle. So handelt es sich beispielsweise bei Templates um Textdateien, und auch Sessioninformationen werden normalerweise in einer Textdatei gepeichert und daraus wieder gelesen. Ebenso wichtig sind Konfigurationsdateien, mit denen das Verhalten von Programmen festgelegt wird und die in vielen Fällen sog. System-Datenbanken ersetzen können.
Eine Spezialform der Textdateien liefern die virtuellen Texte der tdbengine. Solche Texte existieren nur während der Laufzeit des Programms im Arbeitsspeicher. Sie sind derzeit auf 2 GByte beschränkt. Der Vorteil von virtuellen Texten liegt einerseits in der schnellen Bearbeitung und andererseits in der teilweisen Kompatibiltät zu einfachen Zeichenketten. So sind beispielsweise die Funktionen OemToAnsi() und AnsiToOem() auch auf virtuelle Texte anwendbar.
Virtuelle Texte sind dadurch ausgezeichnet, daß ihr Dateiname mit "ramtext:" beginnt. Der Name dieser Datei entspricht dem Rest von Path.
Beispiel:
"ramtext:name1" spricht den virtuellen Text "name1" an.
Ein besonderer virtueller Text hat den Namen "ramtext". Er wird durch die CGI-Funktionen LoadTemplate() und CGIWriteTemplate() initialisiert und bildet die Basis der Template-Funktion Subst().
CGI-Variablen mit dem Namen "text:..." legen automatisch virtuelle Texte gleichen Namens an.
Beispiel: In einem HTML-Formular befindet sich folgende Konstruktion:
<textarea cols=60 rows=20 name="text:inhalt"></textarea>
Das über einen submit-Schalter aufgerufene Programm hat den Inhalt des Textareas komplett im virtuellen Text "ramtext:text:inhalt" und kann beispielsweise so ausgelesen werden:
VAR t : INTEGER
IF t:=Reset("ramtext:text:inhalt")
CGIWriteLn('Inhalt der Textvariablen: <br><pre>')
WHILE NOT EOT(t) DO
CGIWriteHTML(Read(t))
END
CGIWriteLn('</pre><p>')
Close(t)
ELSE
CGIWriteLn('Fehler: Textvariable NICHT gefunden<br>')
END
Textdatei öffnen
Reset(path : STRING) : INTEGER
öffnet eine Textdatei zum Lesen
Rewrite(path : STRING) : INTEGER
erzeugt eine neue Textdatei und öffnet sie zum Schreiben
TAppend(path : STRING) : INTEGER
öffnet eine bestehende Textdatei zum Weiterschreiben
Wichtig: Ist das Funktionsergebnis 0, so darf keinesfalls in diese Datei geschrieben oder daraus gelesen werden.
Expertentip: Der FileHandle 0 bezeichnet die Konsole. Damit kann direkt auf die Kanäle stdin und stdout zugegriffen werden. Beachten Sie aber, daß stdin bei der Initialisierung der CGI-Variablen komplett gelesen wird. Ein read() bzw. readln() mit dem FileHandle 0 bewirkt somit immer, daß das CGI-Programm hängt, denn es wartet auf eine Eingabe, die nie mehr kommen kann!
Kann aus irgendeinem Grund die Textdatei nicht geöffnet werden (Datei ist nicht vorhanden, keine Rechte zum Anlegen der Datei etc.), so wird ein Laufzeitfehler ausgelöst. Diesen kann man mit SetPara('ec 1') (siehe Laufzeitschalter) abfangen:
SetPara('ec 1');
IF t:=Reset('text/meintext.txt')=0
THEN ... Fehlerbehandlung mit TDB_LastError
ELSE
... hier kann mit dem Text gearbeitet werden
END
SetPara('ec 0');
Lesen aus Textdateien
Read(filehandle : INTEGER[,nchars | delchar : CHAR]) : STRING
ReadLn(filehandle : INTEGER) : STRING
Beide Lesefunktionen liefern eine Zeichenkette mit maximal 255 Zeichen. read() liest alle Zeichen, readln() bis zum nächsten Linefeed (asc(10)), wobei Zeilenvorschub (asc(13)) überlesen wird. Beide Funktionen beenden das Lesen, wenn das physikalische Dateiende oder ^Z erreicht wird.
Wird bei read() kein zusätzlicher Parameter angegeben, so wird genau ein Zeichen gelesen. Wird nchars (INTEGER) angegeben, so werden (maximal) nchars Zeichen gelesen. Wird hingegen ein delchar angegeben (beispielsweise ^I=TAB) so wird bis zu diesem Zeichen gelesen. Das Zeichen selbst wird nicht zurückgegeben. In jedem Fall werden maximal 255 Zeichen zurückgeliefert.
Schreiben in Textdateien
Write(filehandle : INTEGER; s : STRING) : STRING
WriteLn(filehandle : INTEGER; s : STRING) : STRING
Bei writeln wird eine Kombination aus Zeilenvorschub und Linefeed nach dem String in die Datei geschrieben.
Datei schliessen
Close(filehandle : INTEGER) : INTEGER
Das Ergebnis ist der IO-Fehlercode des Betriebssystems.
Dateiende ermitteln
EOT(filehandle : INTEGER) : 0|1
Der typische Fall, wenn eine ganze Textdatei bearbeitet wird:
IF t:=Reset(pfad_zur_datei) THEN
WHILE NOT EOT(t) DO
c:=Read(t);
...
END
Close(t)
END;
Die Arbeit mit Templates
Ein Template ist ein Textbaustein, der zunächst in den Arbeitsspeicher geladen wird, um innerhalb des Textes Ersetzungen durchzuführen. Meist handelt es sich um HTML-Seiten bzw. Auszügen daraus. Damit ist es möglich, im Team mit Web-Designern zu arbeiten.
Template laden
LoadTemplate(Pfad : STRING) : INTEGER
Entspricht der Funktion
CopyFile(pfad,"ramtext")
Template ausgeben
CGIWriteTemplate : INTEGER
Entspricht der Funktion
CopyFile("ramtext","con")
Ersetzung ausführen
Subst(Source : STRING; DbNo : INTEGER; Field : INTEGER|STRING [; Mode : INTEGER]) : 0|1
Subst(Source,Target : STRING [; Mode : INTEGER]) : 0|1
DbNo ist ein Database-Handle, der mit OpenDB() erzeugt wird.
Field ist entweder eine Feldnummer oder ein Feldbezeichner als String
Target ist String. Beginnt der String mit "extern:" oder "ramtext:", so wird damit ein entsprechender externer Text bezeichnet:
extern: der Rest des Strings bezeichnet einen Dateinamen
ramtext: der Rest des Strings bezeichnet einen Ramtext bzw. eine CGI-Variable,
deren Namen mit "text:" beginnt.
Mode ist eine Addition der einzelnen Grundmodi
0 : Standardersetzung ohne Bearbeitung (default)
1 : Wird vor der Ersetzung nach HTML übersetzt
2 : Ersetzung erfolgt im Ansi-Zeichensatz
4 : LF wird durch LF+'<br>' ersetzt
8 : ExtNote wird nach der ersten Ersetzung gelöscht (nur in Verbindung mit 1)
16 : Externer Text ist im ASCII-Zeichensatz (nur in Verbindung mit externen Texten)
32: Nur Body-Teil wird gelesen (nur in Verbindung mit externen HTML-Texten)
Das Funktionsergebnis ist 1, wenn die Ersetzung durchgegführt wurde (also im positiven Fall), ansonsten 0. Um alle Vorkommen zu ersetzen kann also beispielsweise folgende Konstruktion verwendet werden:
WHILE Subst(....) DO END
Konfigurationsdateien
Die tdbengine unterstützt in besonderem Maße Konfigurationsdateien, die nach folgendem Schema aufgebaut sind:
[Gruppe 1]
Eintrag1=...
Eintrag2=...
...
[Gruppe 2]
Eintrag1=...
Eintrag2=...
...
Jeder Eintrag kann aus bis zu 255 Zeichen bestehen.
Zur Bearbeitung von derartigen Dateien stellt EASY zwei Funktionen zur Verfügung: SetIdent() und GetIdent().
| SETIDENT(Konfigurationsdatei,Eintrag,Wert) |
schreibt Eintrag=Wert in Konfigurationsdatei |
| GETIDENT(Konfigurationsdatei,Eintrag) |
liefert den zum Eintrag gehörenden Wert |
Einträge werden dabei in der Form »Gruppe.Eintrag« angegeben.
Beispiel:
PROCEDURE Main
VARDEF ini : STRING
ini:='test.ini'
CGIWriteLn('content-type: text/html')
CGIWriteLn('')
SetIdent(ini,'Administrator.Name','Hans Huber')
SetIdent(ini,'Administrator.Passwort','geheim')
SetIdent(ini,'Datenbank.Adressen','database/adressen.dat')
CGICloseBuffer
CGIWrite('<pre>')
CopyFile(ini,'con')
CGIWrite('</pre>')
ENDPROC
Dieses kleine Programm legt die Datei »test.ini« mit folgendem Inhalt an:
[Administrator]
Name=Hans Huber
Passwort=geheim
[Datenbank]
Adressen=database/adressen.dat
Anmerkung: Die erzeugte Datei wird dann auch noch auf dem Bildschirm ausgegeben. Wichtig ist hier der Einsatz von
CGICloseBuffer(), damit der interne Puffer vor dem Kopiervorgang ausgegeben wird.
Mit GetIdent() können die einzelnen Einträge ausgelesen werden.
Beispiel:
GetIdent('test.ini','Administrator.Name) -> 'Hans Huber'
GetIdent('test.ini',Datenbank.Adressen) -> 'database/adressen.dat'
Hinweis
: Beim ersten Zugriff auf eine Konfigurationsdatei wird diese komplett in den Arbeitsspeicher des Computers gelesen und über
eine Baumstruktur dem Programm zur Verfügung gestellt. Deshalb ist der Zugriff extrem schnell.
|