![]() |
Daten an Datei anhängen
Guten Abend ich hab ne Frage
Ich möchte gern Daten an eine Datei anhängen und danach wieder auslesen , das anhängen ist im prinzip nicht die schwierigkeit
Delphi-Quellcode:
Im Prinzip müsste ich mir die größe von MStream und FStream merken um die daten nachher wieder auslesen zu können. Ich müsste dann praktisch an das das ende der neuen datei seeken und vom Ende bis zu Position "Fsteam - Msteam" alles wieder auslesen, die frage ist jetzt, wie kann ich diese positionen speichern ?
procedure TForm1.Button1Click(Sender: TObject);
var FStream : TfileStream; Mstream : TMemoryStream; begin opendialog1.Execute; Mstream := TMemoryStream.Create; FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); // Ans Ende der Datei FStream.Seek(0,soFromEnd); // Daten in Mstream schreiben Memo1.Lines.SaveToStream(MStream); // Daten von MStream in FStream Mstream.SaveToStream(FStream); // Destruktor MStream.Free; Fstream.Free; end; MFG |
Re: Daten an Datei anhängen
Häng sie als Integer hinten dran.
|
Re: Daten an Datei anhängen
Moin svenwel,
schreibe die Länge des angehängten Teils doch ganz an das Ende, dann kannst Du leicht berechnen, wo der angehängte Teil beginnt. |
Re: Daten an Datei anhängen
Einfach in Form eines Strings ? also die größe des angehängten teils in die memo speichern und ans ende hinzufügen ?
|
Re: Daten an Datei anhängen
Schreib die Daten ans Ende, dahinter die Länge und dann noch eine Kennung, das Daten angehängt wurden.
Delphi-Quellcode:
Das ist Pseudocode, es kann also sein, das einige Methoden nicht existieren, aber der Sinn ist klar:
Function GetAppendixInfo (aFile : TString; Var aSize : Integer) : Boolean;
// Liefert True und die Länge des Anhängsels, oder False, wenn keins da ist. Begin aFile.Seek (4, soFromEnd); aFile.ReadInteger (aValue); if aValue <> ccMyPostamble Then Result := False else begin Result := True; aFile.Seek (8, soFromEnd); aFile.ReadInteger (aSize); End End; Procedure AppendData (aFile, aData : TStream); Begin If GetAppendixInfo (aFile, aSizeOfOldData) Then aFile.Seek (aSizeOfOldData, soFromEnd) Else aFile.Seek (0, soFromEnd); aFile.Copy (aData, aData.Size); aFile.WriteInteger (aData.Size + 8); // Daten + 2*Integer aFile.WriteInteger (ccMyPostamble); aFile.Truncate; End; Procedure ReadAppendix (aFile, aData : TStream); Begin If not GetAppendixInfo (aFile, aSizeOfData) Then Raise Exception.Create ('Da is nix'); aFile.Seek (aSizeOfData, soFromEnd); // aSizeOfData ist um 8 bytes grösser (wg Länge und postamble) aData.Copy (aFile, aSizeOfData - 8); End; Wenn ich Daten hinten dran hänge, dann schreibe ich die Daten, dann die Länge, dann eine Kennung Wenn ich Daten lesen will, dann gucke ich erst, ob hinten die Kennung dran ist. Wenn ja, lese ich die 4 bytes davor (die Länge) und dann die Daten. Mit ein bisserl Gehirnschmalz kannst Du mehrere Blöcke hinten dran hängen. |
Re: Daten an Datei anhängen
:wall: Irgendwat mach ich falsch :gruebel:
Delphi-Quellcode:
Also ich hab jetzt des gemacht, was in dem Pseudo Code steht
procedure TForm1.Button1Click(Sender: TObject);
var FStream : TStream; Mstream : TMemoryStream; iMSize : integer; begin Mstream := TMemoryStream.Create; opendialog1.Execute; FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); FStream.Seek(0,soFromEnd); Memo1.Lines.SaveToStream(MStream); FStream.CopyFrom(MStream,0); iMSize := MStream.Size+sizeof(integer); Fstream.Write(iMSize,SizeOf(IMSize)); MStream.Free; Fstream.Free; end; procedure TForm1.Button2Click(Sender: TObject); var FStream : TStream; LStream : Tstream; begin opendialog1.Execute; LStream := TStream.Create; FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); FStream.Seek(sizeof(integer)+4,soFromEnd); LStream.CopyFrom(Fstream,SizeOf(Integer)-4); Memo2.Lines.LoadFromStream(LStream); LStream.Free; Fstream.Free; end; |
Re: Daten an Datei anhängen
Wenn es funktioniert, dann freut's mich. Aber ich würde mir die Mühe machen, eine Kennung hinten ranzuhängen, das wird sicherer.
|
Re: Daten an Datei anhängen
Das funktioniert nicht so
Delphi-Quellcode:
Änder das so um dann sollte es gehen
Fstream.Write(iMSize,SizeOf(IMSize));
Delphi-Quellcode:
Fstream.Write(iMSize,SizeOf(integer));
|
Re: Daten an Datei anhängen
Ich als professioneller kleiner Klugscheisser würde sagen, das Sizeof(IntegerVariable) = SizeOf (Integer), aber egal:
Ich hatte das Posting von svenwel.de nicht richtig gelesen. Also sven: Was Du da geschrieben hast, stammt nicht von meinem Pseudocode. Teil 1: Code zerreissen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
// ***** TStream ist eine abstrakte Basisklasse. Nimm TFileStreams. var FStream : TStream; Mstream : TMemoryStream; iMSize : integer; begin Mstream := TMemoryStream.Create; opendialog1.Execute; FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); // *** Was ist, wenn hier schon was angehängt wurde ? FStream.Seek(0,soFromEnd); Memo1.Lines.SaveToStream(MStream); FStream.CopyFrom(MStream,0); iMSize := MStream.Size+sizeof(integer); Fstream.Write(iMSize,SizeOf(IMSize)); MStream.Free; Fstream.Free; end; procedure TForm1.Button2Click(Sender: TObject); var FStream : TStream; LStream : Tstream; begin opendialog1.Execute; LStream := TStream.Create; FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); // **** Denkfehler, Du gehst ja nicht zum letzten DWORD, sondern zum VORLETZTEN! // richtig sollte es heissen : FStream.Seek (SizeOf (Integer), soFromEnd); FStream.Seek(sizeof(integer)+4,soFromEnd); // ***** Du musst doch erstmal die Datenlänge (iMSize) auslesen, das geht mit // ***** FStream.Read (iMSize, SizeOf (Integer)); LStream.CopyFrom(Fstream,SizeOf(Integer)-4); // ***** Dann musst Du doch an den Anfang der Daten im FStream und DANN erst LStream einlesen, also: // ***** FStream.Seek (iMSize, soFromEnd); // ***** und dann iMSize-SizeOf (Integer) Bytes in LStream kopieren, also: // ***** LStream.CopyFrom (FStream, iMSize - SizeOf (Integer)); Memo2.Lines.LoadFromStream(LStream); // ***** IMMER mit Try...Finally schützen... LStream.Free; Fstream.Free; end; Teil 2: Klugscheissen... Also sieht der Code so aus:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var FStream : TFileStream; LStream : TStringStream; iMSize : Integer; begin opendialog1.Execute; LStream := TStringStream.Create(''); Try FStream := TFileStream.Create(opendialog1.FileName,fmOpenReadWrite); Try // Wieviel Bytes sind denn in der angehängten Nachricht? Gehe zum letzen DWORD im Stream. // Der fängt 4 Bytes von hinten gezählt an (sonst wärs ja nicht der letzte Integer) FStream.Seek (SizeOf (Integer), soFromEnd); FStream.Read (iMSize, SizeOf (Integer)); // So, dann setzen wir uns auf den Anfang der Daten. FStream.Seek (iMSize, soFromEnd); // Wir haben ja 'Länge + 4 Bytes' in iMSize reingeschrieben (siehe oben), also lesen wir // auch genau die Bytes wieder raus. LStream.CopyFrom (FStream, iMSize - SizeOf (Integer)); // Ein TStringstream ist ein bisserl schneller, weil ich den gelesenen String nicht *nochmal* // kopiere. Soweit ich weiss, arbeiten die Strings mit Referenzzählern... Memo2.Lines.Text := LStream.DataString; Finally FStream.Free; End; Finally LStream.Free; End; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz