Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Daten an Datei anhängen (https://www.delphipraxis.net/46493-daten-datei-anhaengen.html)

svenwel.de 25. Mai 2005 19:42


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:
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;
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 ?


MFG

Luckie 25. Mai 2005 19:46

Re: Daten an Datei anhängen
 
Häng sie als Integer hinten dran.

Christian Seehase 25. Mai 2005 19:47

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.

svenwel.de 25. Mai 2005 20:09

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 ?

alzaimar 25. Mai 2005 21:08

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:
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;
Das ist Pseudocode, es kann also sein, das einige Methoden nicht existieren, aber der Sinn ist klar:
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.

svenwel.de 25. Mai 2005 22:24

Re: Daten an Datei anhängen
 
:wall: Irgendwat mach ich falsch :gruebel:

Delphi-Quellcode:
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;
Also ich hab jetzt des gemacht, was in dem Pseudo Code steht

alzaimar 26. Mai 2005 06:50

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.

franktron 26. Mai 2005 08:40

Re: Daten an Datei anhängen
 
Das funktioniert nicht so
Delphi-Quellcode:
Fstream.Write(iMSize,SizeOf(IMSize));
Änder das so um dann sollte es gehen
Delphi-Quellcode:
Fstream.Write(iMSize,SizeOf(integer));

alzaimar 26. Mai 2005 10:43

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