|
Records in einem FileStreams speichern.
Hallo, das ist mein erstes Tutorial, deshalb last Gnade vor Recht ergehen. Damit Daten auch dem Beenden eines Programms erhalten bleiben, müssen sie dauerhaft vorliegen, sprich sie müssen auf einen Datenträger, vorzugsweise auf eine Festplatte abgespeichert werden. Dieses Beispielprogramm besteht aus 3 Units. 1. Const_DatUnit / Hier werden globale Konstanten abgelegt. 2. StreamUnit / Hier sind die TFileStrem-Funktionen abgelegt 3. HauptprogrammUnit1 / Hier werden die Funktionen angewendet. Bewusst wurden auf komplexre Objekte versichtet und im Sinne der Grundlagenvermittlung weitestgehend auf elementare Bausteine zurückgegriffen. In unserem Beispiel werden wir auf einen benutzerdefinierten Datentyp (Record) zurückgreifen. Da es in der Regel üblich ist, bei Records mit einer Adressen-Datenbank zu arbeiten, habe ich mich dazu entschlossen von dieser Regel einmal abzuweichen. Ich werde in diesem Beispiel Messwerte auf die Festplatte abspeichern, diese Messwerte (kurz: MW) werden normalerweise von einer SPS übermittelt. In unserem Fall müssen wir sie leider selber eingeben. Der Record besteht aus: 1. Maschinen-Nr. also an welcher Maschine ist der MW angefallen 2. Messstelle-Nr. an welcher Messstelle dieser Maschine ist der MW gemessen worden 3. Messwert der eigentliche MW 4. Datum/Uhrzeit Wann ist der MW angefallen sprich Datum und Uhrzeit 5. Messwert Gelesen Flag Ist der MW schon in eine Datenbank übertragen werden. 6. Messwert Flag Status Flag
Delphi-Quellcode:
Das ganze soll ja mit einem FileStream – Objekt auf die Festplatte gespeichert werden, des halben werden wir folgende Methoden behandeln:
{
******************************************************************************** * Unit: Const_DatUnit * * letz.Änderung: 15.01.2007 * *------------------------------------------------------------------------------* * Beschreibung: In dieser Unit werden die Konstanten für * * StreamVerwaltungProject deklariert * ******************************************************************************** } unit Const_DatUnit; interface Uses Classes; const // Konstanten für die Strings MA_ZEICH_ANZ = 3; MS_ZEICH_ANZ = 2; // Datenbezeichnungen LW_BEZ = 'c:\'; // Laufwerks-Bezeichnung ORDNER_NAME = 'StreamDatenOrdner'; // Verzeichnis-Name DATEI_NAME = '\MessWertDaten'; // Name der Datei DATEI_ERW = '.dxt'; // Datei-Erweiterung ORDNER_PFAD = LW_BEZ + ORDNER_NAME; STREAM_PFAD = LW_BEZ + ORDNER_NAME + DATEI_NAME + DATEI_ERW; type { ******************************************************************************** * Der Daten-Record der als Datensatz verarbeitet werden soll. * ******************************************************************************** } TMW_Stream_Rec = Record stfMaNr: string[MA_ZEICH_ANZ]; // Maschinen-Nr. stfMs : string[MS_ZEICH_ANZ]; // Mess-Stellen-Nr. dblMw : double; // Mess-Wert als double dtDatumUhrzeit: TDateTime; // System Datum u. Uhrzeit als der MW // übertragen worden ist. blnMWGelesen: boolean; // bei TRUE ist der Wert in die Daten- // bank übertragen worden. blnMWFlag: boolean; // Status des Records: TRUE= Fehler end; {------------------------------------------------------------------------------} { ******************************************************************************** * Globale Variable * ******************************************************************************** } var DateiName: String; // Hier wird der Stream_Pfad abgespeichert implementation end. TFileStream.Create TFileStream.free TFileStream.Position TFileStream.Seek TFileStream.WriteBuffer TFileStream.ReadBuffer TFileStream.Size Diese Methoden werden in der Unit: StreamUnit benutzt.
Delphi-Quellcode:
{
******************************************************************************** * Unit: StreamUnit * * letz. Änderung: 17.01.2007 * *------------------------------------------------------------------------------* } unit StreamUnit; interface Uses SysUtils, Classes, Dialogs, Forms, FileCtrl, Const_DatUnit; function Ordner_anlegen (OrdnerName: string): boolean; function Stream_oeffnen (var f: TFileStream ;const DateiName: string): boolean; function Stream_Schliessen (var f:TFileStream): boolean; function Stream_MW_Rec_Anhaengen (var f: TFileStream; MWRec: TMW_Stream_Rec): boolean; function Stream_MW_Rec_Lesen (var f: TFileStream; var MWRec: TMW_Stream_Rec; DatensatzNr: integer): boolean; function Stream_MW_Rec_DatenSatzAnzahl (var f: TFileStream; MWRec: TMW_Stream_Rec): integer; function Stream_MW_Rec_Aendern (var f: TFileStream; MWRec: TMW_Stream_Rec; DatenSatzNr: integer): boolean; implementation { ******************************************************************************** * Ordner_anlegen(): Mit dieser Function wird der Ordner angelegt * **----------------------------------------------------------------------------** * Eingabe: Ordner-Name * * FunctionsWert: TRUE = Der Ordner war schon vorhanden * * FALSE = Der Ordner wurde neu angelegt * * Beschreibung: Mit dieser Funktion wird geprüft, ob der Ordner der in * * OrdnerName angegeben worden ist vorhanden ist. Ist er nicht * * vorhanden so wird er neu angelegt. * * Wenn der Ordner nicht angelegt werden konnte, wird eine Fehler-* * Meldung angezeigt. * ******************************************************************************** } function Ordner_anlegen (OrdnerName: string): boolean; begin if not DirectoryExists(OrdnerName) then if not CreateDir(OrdnerName) then begin raise Exception.Create('Der Ordner '+OrdnerName+ ' wurde nicht angelegt'); end else begin result:= FALSE; // Ordner neu angelegt end else result:= TRUE; // Ordner war schon vorhanden end; {------------------------------------------------------------------------------} { ******************************************************************************** * FileStream Functionen und Proceduren * *------------------------------------------------------------------------------* * letz.Änderung: 17.01.2007 * ******************************************************************************** } { ******************************************************************************** * Stream_oeffnen(): Mit dieser Function wird ein Stream geöffnet * **-----------------------------------------------------------------------------* * Eingabe: var f: TFileStream * * const DateiName: string // Der DateiName muss komplett mit einem * * Path sein! * * FunctionsWert: TRUE = Der Stream ist zum lesen und schreiben geöffnet worden * * FALSE = Der Stream (DateiName ist neu angelegt worden * * Beschreibung: Mit dieser Function wird der Stream geöffnet. Ist er bis jetzt * * nicht vorhanden gewesen, so wird er neu angelegt. * * Die Dateien sind ohne Einschränkungen zum Lesen und Schreiben * * Dies wird mit FmShareDenyNone eingestellt. * ******************************************************************************** } function Stream_oeffnen (var f: TFileStream ;const DateiName: string): boolean; begin result:= TRUE; try {-- FileStream zum Lesen u. Schreiben uneingeschränkt öffnen -----------} f:= TFileStream.Create(DateiName, fmOpenReadWrite or fmShareDenyNone) except try { FileStream neu anlegen, tritt hier ein Fehler auf so wird das Prg. ab- } { gebrochen und zur der aufrufende Routine zurückgesprungen. } f:= TFileStream.Create(DateiName, fmCreate or fmShareDenyNone); except ShowMessage('Fehler beim Erzeugen der Datei:'+#13+DateiName); Exit; // Zur aufrufenden Routine zurück. end; result:= FALSE; end; end; { ******************************************************************************** * Stream_Schliessen(): Mit dieser Function wird ein Stream geschlossen * **-----------------------------------------------------------------------------* * Eingabe: var f: TFileStream * * FunctionsWert: TRUE = Alles O.K. der Stream ist geschlossen worden. * * FALSE = Es ist ein Fehler beim Schliessen des Streams aufge- * * treten. Wahrscheinlich war der Stream nicht geöffnet. * * Beschreibung: Mit dieser Function wird der Stream geschlossen. * * War der Stream nicht geöffnet, so wird FALSE zurückgegeben. * ******************************************************************************** } function Stream_Schliessen (var f:TFileStream): boolean; begin result:= TRUE; try f.Free; // FileStream schliessen except result:= FALSE; end; end; { ******************************************************************************** * Stream_MW_Rec_Anhaengen(): Mit dieser Function wird der Datensatz am Ende * * des Stream angehängt. * **-----------------------------------------------------------------------------* * Eingabe: var f: TFileStream * * TMW_Stream_Rec * * FunctionsWert: TRUE = Alles O.K. der Datensatz ist in den Stream gespeichert * * worden. * * FALSE = Es ist ein Fehler beim Speichern aufgetreten. * * Beschreibung: Mit dieser Function wird der Datensatz am Ende des Streams * * angehängt. * * War der Stream nicht geöffnet, so wird FALSE zurückgegeben. * ******************************************************************************** } function Stream_MW_Rec_Anhaengen (var f: TFileStream; MWRec: TMW_Stream_Rec): boolean; begin try f.Position:=0; f.Seek(0, soFromEnd); // Datenzeiger auf das Ende des Streams setzen. f.WriteBuffer(MWRec, SizeOf(TMW_Stream_Rec)); result:= TRUE; except ShowMessage('Es ist beim Datensatz speichern ein Fehler aufgetreten!'); result:= FALSE; end; end; { ******************************************************************************** * Stream_MW_Rec_Aendern(): Mit dieser Function werden geänderte Daten in den * * Stream zurückgeschrieben * **-----------------------------------------------------------------------------* * Eingabe: var f: TFileStream * * MWRec: TMW_Stream_Rec // Datensatz * * DatensatzNr: integer // Das ist die Datensatz-Nr die zurückge-* * schrieben wird. * * FunctionsWert: TRUE = Alles O.K. der Datensatz ist in den Stream gespeichert * * worden. * * FALSE = Es ist ein Fehler beim Speichern aufgetreten. * * Beschreibung: Mit dieser Function wird der geänderte Datensatz in dem Stream * * zurückgeschrieben * * War der Stream nicht geöffnet, so wird FALSE zurückgegeben. * ******************************************************************************** } function Stream_MW_Rec_Aendern (var f: TFileStream; MWRec: TMW_Stream_Rec; DatenSatzNr: integer): boolean; begin try f.Position:=0; f.Seek((SizeOF(TMW_Stream_Rec)*DatenSatzNr), soFromBeginning); f.WriteBuffer(MWRec, SizeOf(TMW_Stream_Rec)); result:= TRUE; except ShowMessage('Es ist beim Datensatz zurückschreiben in den Stream'+ ' ein Fehler aufgetreten!'); result:= FALSE; end; end; { ******************************************************************************** * Stream_MW_Rec_Lesen(): Mit dieser Function wird der Datensatz aus dem * * Stream gelesen und in den Record gespeichert * **-----------------------------------------------------------------------------* * Eingabe: var f: TFileStream * * var MWRec: TMW_Stream_Rec * * DatensatzNr: integer; * * FunctionsWert: TRUE = Alles O.K. der Datensatz ist aus dem Stream gelesen * * worden. * * FALSE = Es ist ein Fehler beim Lesen aufgetreten. * * Beschreibung: Mit dieser Function wird der Datensatz mit der DatensatzNr * * angegeben worden ist, in den TMW_Stream_Rec gelesen. * * Der Datensatz-Zeiger wird auf den Anfang des Streams gesetz * * (soFromBeginning). * * Mit der Anweisungen: SitzeOf(TMW_Stream_Rec)*DatensatzNr * * wird die Byte-Anzahl ermittelt, die der Datensatz-Zeiger * * weiter bewegt werden soll. * ******************************************************************************** } function Stream_MW_Rec_Lesen (var f: TFileStream; var MWRec: TMW_Stream_Rec; DatensatzNr: integer): boolean; begin try f.Position:=0; // An dieser Stelle wird der Datei-Zeiger auf den zu lesenden // Datensatz gestellt. Durch -soFromBeginning- wird der Dateizeiger // auf den Anfang gesellt. f.Seek((SizeOf(TMW_Stream_Rec)*DatensatzNr), soFromBeginning); f.ReadBuffer(MWRec, SizeOf(TMW_Stream_Rec)); result:= TRUE; except ShowMessage('Es ist beim Datensatz lesen ein Fehler aufgetreten!'); result:= FALSE; end; end; { ******************************************************************************** * Stream_MW_Rec_DatenSatzAnzahl(): Mit dieser Function wird die Anzahl * * der Datensatze im Stream bestimmt. * **----------------------------------------------------------------------------** * Eingabe: var f: TFileStream * * MWRec: TMW_Stream_Rec * * FunctionsWert: Anzahl der Datensätze die im Stream vorhanden sind. * * Beschreibung: Mit f.Sitze wird die gesamte Anzahl der Bytes im Stream be- * * stimmt. Die Gesamtzahl Bytes / Anzahl Bytes im Record ergeben * * die Anzahl der Datensätze im Stream. * * dieser Function wird der Datensatz mit der DatensatzNr * ******************************************************************************** } function Stream_MW_Rec_DatenSatzAnzahl (var f: TFileStream; MWRec: TMW_Stream_Rec): integer; begin result:= 0; if f.Size>0 then begin // Berechnung: Gesamte Stream-Lämge / TMW_Stream_Rec // Das ergibt die Datensatz-Anzahl result:= trunc(f.Size/SizeOf(TMW_Stream_Rec)); end; end; initialization end. An dieser Stelle nun kommt die HauptprogammUnit1 Es ist von der Benutzerführung sehr einfach gehalten und nicht gerade komfortabel, aber soll ja nur die TFileStream – Methoden in der Anwendung zeigen. 1. Datensätze eingeben: Wobei nur die Maschinen – Nr., Messstellen - Nr. und der MW eingegeben werden muss. Das Datum und die Uhrzeit wird zum Zeitpunkt des Abspeicherns von der System – Zeit genommen und die beiden Flags werden dabei auf FALSE gesetzt. 2. Alle Datensätze anzeigen: Hier werden alle Datensätze in einem StringGrid angezeigt 3. Datensatz suchen: Hier wird nur nach den Maschinen – Nr. gesucht und zwar der erste Datensatz der die gleiche Maschine – Nr. besitzt wie der gesuchte. 4. Datensatz ändern: Es wird dafür die Maschinen – Nr. in das Suchfeld eingetragen und anschließend auf den Such-Button gedrückt. Wenn der Gesuchte Datensatz angezeigt wird können die Maschinen – Nr. und die Messstelle – Nr. geändert werden. Darauf hin wird der Änderungs-Button gedrückt und der geänderte Datensatz wird im FileStream abgespeicher. So das sind die grundlegenden Sachen, der Rest ist im Quell-Code dokumentiert.
Delphi-Quellcode:
unit HauptprogrammUnit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, ComCtrls, Const_DatUnit, StreamUnit, ExtCtrls; type TForm1 = class(TForm) PageControl1: TPageControl; TabSheet1: TTabSheet; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; DatSatzSpeichernButton: TButton; TabSheet2: TTabSheet; StringGrid1: TStringGrid; Button2: TButton; TabSheet3: TTabSheet; Label6: TLabel; Button3: TButton; MaschinenNr_Suchen_Edit6: TEdit; Panel1: TPanel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Label11: TLabel; Label12: TLabel; Label13: TLabel; Edit7: TEdit; Edit8: TEdit; Edit9: TEdit; Edit10: TEdit; Edit11: TEdit; Button4: TButton; StatusBar1: TStatusBar; Label7: TLabel; Edit12: TEdit; Label14: TLabel; Edit13: TEdit; Label15: TLabel; Label16: TLabel; Label17: TLabel; Edit6: TEdit; Button1: TButton; procedure FormCreate(Sender: TObject); procedure DatSatzSpeichernButtonClick(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } MW1: TMW_Stream_Rec; intDatSatz: integer; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); var f: TFileStream; intDatensatzNr: integer; intDatensatzAnzahl: integer; begin // Alle Datensatz anzeigen // FileStream öffnen if not Stream_oeffnen (f, Dateiname) then begin ShowMessage('Die Datei '+ DateiName + ' ist neu angelegt worden!'); end; // Anzahl Datensätz ermittlen intDatensatzAnzahl:= Stream_MW_Rec_DatenSatzAnzahl (f, MW1); intDatensatzNr:= 0; for intDatenSatzNr := 0 to intDatensatzAnzahl - 1 do begin Stream_MW_Rec_Lesen (f, MW1, intDatensatzNr); with StringGrid1 do begin Cells[0,1+intDatensatzNr]:= inttostr(intDatensatzNr+1); Cells[1,1+intDatensatzNr]:= MW1.stfMaNr; Cells[2,1+intDatensatzNr]:= MW1.stfMs; Cells[3,1+intDatensatzNr]:= floattostr(MW1.dblMw); Cells[4,1+intDatensatzNr]:= DateTimetostr(MW1.dtDatumUhrzeit); end; end; Stream_Schliessen (f); end; procedure TForm1.Button3Click(Sender: TObject); var f: TFileStream; intDatensatzNr: integer; intDatensatzAnzahl: integer; strMaschinenNr: string; // Gesuchte Maschinen-Nr. begin if not Stream_oeffnen (f, Dateiname) then begin ShowMessage('Die Datei '+ DateiName + ' ist neu angelegt worden!'); end; // Anzahl Datensätz ermittlen intDatensatzAnzahl:= Stream_MW_Rec_DatenSatzAnzahl (f, MW1); // Gesuchte Maschinen-Nr eingeben strMaschinenNr:= MaschinenNr_Suchen_Edit6.Text; intDatensatzNr:= 0; // DatensatzNr auf 0 setzen. // Es werden die Datensätz solange durchlaufen bis eine Übereinstimmung // gefunden worden ist. for intDatenSatzNr := 0 to intDatensatzAnzahl - 1 do begin Stream_MW_Rec_Lesen (f, MW1, intDatensatzNr); if MW1.stfMaNr = strMaschinenNr then begin with StringGrid1 do begin Label15.Caption:= inttostr(intDatensatzNr+1); intDatSatz:= intDatensatzNr; // Merken welcher Datensatz Edit7.Text := MW1.stfMaNr; Edit8.Text := MW1.stfMs; Edit9.Text := floattostr(MW1.dblMw); Edit6.Text := dateTimetostr(MW1.dtDatumUhrzeit); Edit10.Text := booltostr(MW1.blnMWGelesen); Edit11.Text := booltostr(MW1.blnMWFlag); break; // Datensatz ist gefunden die Schleife wird abgebrochen end; end; end; Stream_Schliessen (f); end; procedure TForm1.Button4Click(Sender: TObject); var f: TFileStream; intDatensatzNr: integer; intDatensatzAnzahl: integer; begin // Nur die Maschinen-Nr. und die Meßstelle können geändert werden. // Die anderen Daten im Datensatz sind natürlich auch möglich. MW1.stfMaNr:= Edit7.Text; MW1.stfMs:= Edit8.Text; if not Stream_oeffnen (f, Dateiname) then begin ShowMessage('Die Datei '+ DateiName + ' ist neu angelegt worden!'); end; // Anzahl Datensätz ermittlen intDatensatzAnzahl:= Stream_MW_Rec_DatenSatzAnzahl (f, MW1); // Gesuchte Maschinen-Nr eingeben Stream_MW_Rec_Aendern (f, MW1, intDatSatz); Stream_Schliessen (f); end; procedure TForm1.DatSatzSpeichernButtonClick(Sender: TObject); var f: TFilestream; begin // Datensatz Eingeben MW1.stfMaNr:= Edit1.Text; MW1.stfMs:= Edit2.Text; MW1.dblMw:= strtofloat(Edit3.text); MW1.dtDatumUhrzeit:= now(); Edit4.Text:= dateTimetostr (MW1.dtDatumUhrzeit); MW1.blnMWGelesen:= FALSE; MW1.blnMWFlag:= FALSE; Edit12.Text := booltostr(MW1.blnMWGelesen); Edit13.Text := booltostr(MW1.blnMWFlag); // FileStream öffnen if not Stream_oeffnen (f, Dateiname) then begin ShowMessage('Die Datei '+ DateiName + ' ist neu angelegt worden!'); end; // Datensatz - Record an die Datei anhängen Stream_MW_Rec_Anhaengen (f, MW1); Stream_Schliessen (f); end; procedure TForm1.FormCreate(Sender: TObject); begin {* Prüfen ob der Ordner: c;\StreamDatenOrdner vorhanden ist, wenn nicht wird } {* er auf dem c:\ laufwerk angelegt. } Ordner_Anlegen(ORDNER_PFAD); DateiName:= STREAM_PFAD; end; end. Ich hoffe, dass Ihr damit einigermaßen zu Recht kommt. Mit freundlichen Grüßen Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
|
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |