Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi beliebige Datei in Stream speichern (https://www.delphipraxis.net/2515-beliebige-datei-stream-speichern.html)

Evilboyz 27. Jan 2003 14:42


beliebige Datei in Stream speichern
 
Hallo Forum!

Wie schreibe ich eine beliebige Datei in einen Stream und wie bekomme ich die Datei dort wieder heraus?
Soweit ich das bisher herausgefunden habe, muss ich auf alle Fälle SaveToStream verwenden. Ich habe jetzt versucht, mit AssignFile eine Dateivariable zu initialisieren um diese dann per SaveToStream in einen Stream zu packen, bin ich da völlig auf dem Holzweg? :freak:

Evilboyz 27. Jan 2003 15:12

So, also im Moment sieht mein Code wie folgt aus:

Code:
procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var DataEnvelope : TStream;
      data :        file;
begin
     AssignFile(data, 'datei\test.exe');
     data.SaveToStream(DataEnvelope, dfBinary);
     closefile(data);
     Socket.SendStream(DataEnvelope);
     DataEnvelope.Free;
end;
Als Fehlermeldung bekomme ich in der Zeite, in der SaveToStream steht: "Record, Objekt oder Klassentyp erforderlich"

Christian Seehase 27. Jan 2003 15:46

Moin Evilboyz,

Du vermischt da verschiedene Methoden auf Dateien zuzugreifen.
Schau Dir am Besten mal TFileStream an.

Beispiel:

Delphi-Quellcode:
var
  fsWork : TFileStream;
  sBuffer : string;

begin
  fsWork := TFileStream.Create(DateiPfad,Modus);
  sBuffer := StringOfChar(#00,fsWork.Size);
  try
    // Komplett in Buffer einlesen
    fsWork.Read(sBuffer[1],fsWork.Size);
  finally
    FreeAndNil(fsWork);
  end;
  // Mit dem Buffer arbeiten
end;

Evilboyz 28. Jan 2003 08:12

Ahja, jetzt scheint es zu funktionieren ... Danke Dir!!!

:coder:

Evilboyz 28. Jan 2003 09:26

Doch noch nicht ganz ....
Also die Sache mit
Zitat:

Zitat von Christian Seehase
fsWork := TFileStream.Create(DateiPfad,Modus);

ist mir jetzt klar, was passiert aber in dieser Zeile?
Zitat:

Zitat von Christian Seehase
sBuffer := StringOfChar(#00,fsWork.Size);

StringOfChar gibt jetzt also (lt. Hilfe), fsWork.size mal #00 zurück, aber was hat es mitdem #00 auf sich? :freak:

Was ich außerdem noch nicht hinbekommen habe, ist den Stream auf der anderen Seite wieder in eine Datei zu schreiben, ich hab den jetzt über SendStream abgeschickt und auf Clientseite per receiveBuf empfangen (irgendwas kommt da immerhin schonmal an). SaveToFile meckert mir der Compiler dann allerdings an und sagt: "Undefinierter Bezeichner: SaveToFile"
Irgendwie habe ich den Eindruck, dass ich immernoch verschiedene Möglichkeiten der Übertragung vermische!

Evilboyz 28. Jan 2003 11:41

Tja, da ich natürlich nicht aufgebe und beim Nachlesen (Entwicklerhandbuch - Borland D5) immer wieder neue Erkenntnisse erlange (so sollte es ja auch sein), schreibe ich eben mal wieder selber eine Antwort.
Ich sende also, wie schon gesagt, per SendStream meinen Stream. lt. Seite 30-12 (ist ja auch egal) scheint es aber keine ReceiveStream Methode auf der anderen Seite zu geben. Wenn ich die Daten per ReceiveBuf empfange, dann scheint die Übertragung Byteweise statt zu finden und ich muss irgendwie darauf warten, bis die Übertragung fertig ist. Wie also mache ich das?
Ja und die Sache mit #00 ist mir nach wie vor unklar!

Christian Seehase 28. Jan 2003 12:05

Moin Evilboyz,

statt Byteweise zu lesen, könntest Du ja auch immer Blockweise lesen, bis nichts mehr zu lesen ist (Rückgabewert -1).

Mit dem StringOfChar wird die Buffergrösse auf den zumindest erforderlichen Platz gesetzt, und gleichzeitig auf #00 initialisiert, damit der Buffer einen definierten Inhalt hat.
Wenn es sich um grössere Dateien handelt, könnte man natürlich auch (wie bei ReceiveBuf ;-) ) Blockweise lesen, und dann je Lesevorgang die Initialisierung wiederholen, damit zumindest der Rest des Buffers (falls die Buffergrösse kein Vielfaches der zu lesenden Anzahl Byte ist) mit einem definierten Wert belegt ist.

Die #00 nehme ich, da dies ein Wert ist, der zumindest in Texten eigentlich nicht auftauchen kann (Unicode mal ausgenommen), und somit das erste auftreten einer #00 sich oft als Ende der Daten ansehen lässt (wie bei nullterminierten Strings, wie sie bei den Windows API Funktionen üblich sind).

Beim Einlesen (ob nun über TFileStream.Read, oder über ReceiveBuf) könnte das dann so aussehen:
  1. Buffer initialisieren
  2. Daten lesen (Länge = Bufferlänge)
  3. Keine Daten gelesen dann fertig
  4. Daten in gelesener Länge verarbeiten
  5. Weiter mit 1

Evilboyz 28. Jan 2003 15:47

Hi,

ich bekomme es immer noch nicht hin! :cry: Folgenden Code habe ich jetzt also auf Serverseite. Wie finde ich bei SendBuf nun aber die den Int - Wert, den ich übergeben muss? Wenn ich testhalber 1000 eintrage wird etwas gesendet, wenn ich die Länge von SBuffer ermitteln und diese übergeben will, bekomme ich einen Fehler beim Compilieren.
Code:
procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var fsWork : TFileStream;
      sBuffer : String;
begin
     Events.Lines.Add(Socket.ReceiveText);

     fsWork := TFileStream.Create('datei\test.exe', fmOpenRead);
     sBuffer := StringOfChar(#00,fsWork.Size);
     try
         Komplett in Buffer einlesen
        fsWork.Read(sBuffer[1],fsWork.Size);
     finally
        FreeAndNil(fsWork);
     end;
         Socket.SendBuf(sBuffer,1000);
end;
Auf Clientseite kann ich doch nun mit
Code:
Socket.ReceiveBuf(Data, Socket.ReceiveLength);
die empfangenen Daten in "Data" (Data : TStream) schreiben, oder?
Langsam komme ich mir echt schon blöd vor, aber ich stehe voll auf dem Schlauch!

Evilboyz 28. Jan 2003 15:50

Zitat:

Zitat von Christian Seehase
  1. Buffer initialisieren
  2. Daten lesen (Länge = Bufferlänge)
  3. Keine Daten gelesen dann fertig
  4. Daten in gelesener Länge verarbeiten
  5. Weiter mit 1

Das bedeutet also, ich lese die Daten in meine Buffervariable (String) und fülle eine Datei nach und nach mit diesen empfangenen Teilstrings. Das wiederhole ich solange, bis keine Daten mehr gelesen werden. :pale:

Evilboyz 28. Jan 2003 15:56

ist dieser Code richtig???
Code:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
  var Data : TStream;
      sBuffer : String;
begin
     while Socket.ReceiveBuf(sBuffer, Socket.ReceiveLength)<>-1 do begin
           Data.Write(sBuffer, length(sBuffer));
     end;
     Data.Free;
end;
:coder: ... *nichtaufgibt*

Christian Seehase 28. Jan 2003 16:34

Moin Evilboyz,

in Deinem Beispiel fehlt die Initialisierung des Buffers, ausserdem muss, wenn der Buffer ein String ist zwingend die Position angeben werden, ab der aus dem Buffer gelesen, bzw. ab der in den Buffer geschrieben werden soll. Ausserdem ist TStream eine abstrakte Klasse, die man nur als Basisklasse für Ableitungen eigener Klassen nutzen sollte (wenn Du hier im Forum mal nach "abstrakt" suchst, solltest Du dazu eine Nähere Erklärung finden):

Delphi-Quellcode:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);

var
  fsData : TFileStream; // Nur mal als Beispiel einen FileStream angenommen
  sBuffer : String;
begin
  // FileStream zum Schreiben öffnen
  fsData := TFileStream.Create('IrgendeinDateiPfad',fmOpenWrite);
  try
    // Buffer initialisieren (erst hier. Falls TFileStream.Create schiefgeht, muss der Buffer ja nicht initialisiert sein
    sBuffer := StringOfChar(#00,Socket.ReceiveLength);
    // Da in der Maximallänge gelesen wird, braucht man keine Schleife
    // Wichtig: sBuffer[1], damit an der ersten Stelle des Buffers geschrieben wird
    if Socket.ReceiveBuf(sBuffer[1],Socket.ReceiveLength) <> -1 then
    begin
      // Eingelesene Daten in Datei wegschreiben, wenn etwas eingelesen wurde
      fsData.Write(sBuffer[1],Length(sBuffer));
    end;    
  finally
    // Stream wieder freigeben
    FreeAndNil(fsData);
  end;
end;
Ich hab' Dein Beispiel mal "ergänzt".
So müsste es eigentlich gehen. Schau doch mal, ob Du damit klarkommst.

Evilboyz 29. Jan 2003 10:54

:bounce1: :bounce2: :spin: :mrgreen:
Es funktioniert!!!! Vielen Dank für die Hilfe!

Eine kleine Anmerkung habe ich allerdings noch. Da die Datei in mehreren Blöcken empfangen wird, ist es wichtig, darauf zu achten, dass der Zeiger im FileStream vor dem Schreiben jedes Blocks am Ende steht!
Code:
fsData.Seek(0, SoFromEnd);
Ansonsten wird die Datei niemals größer als 3 KB ... :mrgreen:

Christian Seehase 29. Jan 2003 12:27

Moin Evilboyz,

Zitat:

Zitat von Evilboyz
Ansonsten wird die Datei niemals größer als 3 KB ... :mrgreen:

Das spart dann aber ungeheuer Platz :mrgreen:

Jan 29. Jan 2003 17:16

Hi ihrs!
Ich hab das jetzt mal Interressehalber nachgemacht, und sitze da jetzt schon ca 3 stunden dran, so langsam.....
Naja, guckt euch das vielleicht mal an:

Server:

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
     recbuffer:string;
     recstream:tfilestream;
begin
  recbuffer:=stringofchar(#00,socket.ReceiveLength);
  try
     socket.ReceiveBuf(recbuffer[1], length(recbuffer));
    recstream:=tfilestream.create('c:\test.exe', fmopenwrite);
    recstream.Write(recbuffer[1], length(recbuffer));
  finally
     freeandnil(recbuffer);
    freeandnil(recstream);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
serversocket1.Active:=true;
serversocket1.Open;
end;

end.

Client:

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin
  if opendialog1.Execute then
  begin
    edit2.Text:=form1.OpenDialog1.FileName;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
     meanfile : tfilestream;
     meanbuffer : string;
begin
  if (edit1.Text<>'') and (edit2.text<>'') then
  begin
    try
      clientsocket1.Address := edit1.Text;
    except
      showmessage('geben sie eine gültige IP-Addresse an!');
    end;
    clientsocket1.active:=true;
    meanfile:=tfilestream.create(edit2.text, fmopenread);
    meanbuffer:=stringofchar(#00, meanfile.size);
    try
      meanfile.read(meanbuffer[1], length(meanbuffer));
      clientsocket1.Open;
      if form1.ClientSocket1.socket.Sendbuf(meanbuffer, length(meanbuffer))<>-1 then
        showmessage('Datei erfolgreich verschickt');
    finally
      freeandnil(meanfile);
      clientsocket1.close;
      clientsocket1.Free;
    end;
  end;
end;

end.
Ich erhalte beim Schicken einer Datei beim Servertool einen error unbekannter Herkunft (10052) und einen "asyncronous socket error" aber ich habe eigentlich bei beiden Programmen den Port auf 22 gestellt.
*Helpneed*
Also danke schonmal für alle Antworten!
BB!
Jan

Evilboyz 30. Jan 2003 07:58

Hallo Jan,

also grundsätzlich konnte ich in Deinem Code mal keinen Fehler entdecken. Fehler 10052 bedeutet laut Delphi Hilfe "Verbindung pausiert, wenn SO_KEEPALIVE gesetzt wird." .... Soweit ich mich erinnern kann, hatte ich den Fehler auch hin und wieder, wenn eine Seite des Programms unplanmäßig beendet wurde.
Ansonsten hast Du, um die Verbindung aufzubauen, Socket.open verwendet, ich habe das über socket.active := true gemacht, aber das kann ja eigentlich keinen Unterschied machen!
Außerdem habe ich (siehe weiter oben) den Filestream vor dem schreiben beim Empfänger auf die letzte Position gesetzt. Das hat zwar sicher nichts mit Deinem Problem zu tun, allerdings habe ich damit noch ein Problem! Und zwar wird die Datei bei mir wunderbar übertragen, allerdings schleichen sich beim Schreiben dann falsche Bits, nämlich die der Bufferinitialisierung, ein, wenn meine Datei über 100 KB hat. Hat einer eine Idee, woran das liegen könnte?
Ich poste einfach mal meinen Code ... @jan: Vielleicht hilft er Dir ja weiter!?!

Server (Dateisender):
Code:
procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var fsWork : TFileStream;
      sBuffer, sIncome : String;
begin
     sIncome := Socket.ReceiveText;

     if sIncome='GetUpdate' then begin
          fsWork := TFileStream.Create('datei\bindif.exe', fmOpenRead);
          sBuffer := StringOfChar(#0,fsWork.Size);
          try
             // Komplett in Buffer einlesen
             fsWork.Read(sBuffer[1],fsWork.Size);
          finally
             FreeAndNil(fsWork);
          end;
          if Socket.SendBuf(sBuffer[1],Length(sBuffer))=-1 then
             showMessage('Es konnte keine Datei übertragen werden')
          else begin
              Events.Lines.Add('Datei wurde erfolgreich an Client übertragen');
          end;
     end
end;

procedure TForm1.ConnectClick(Sender: TObject);
begin
     ServerSocket.Port := StrToInt(Port.Text);
     ServerSocket.active := true;
     PageControl.ActivePage := TabSheet1;
end;

procedure TForm1.DisconnectClick(Sender: TObject);
begin
     ServerSocket.active:=false;
     Events.Lines.Add('Server disconnected');
     Clients.Text := '0';
end;
Client (Dateiempfänger):
Code:
procedure TForm1.ConnectClick(Sender: TObject);
begin
    ClientSocket1.Port := StrToInt(Port.Text);
    ClientSocket1.Host := Host.Text;
    ClientSocket1.active := true;
end;

procedure TForm1.DisconnectClick(Sender: TObject);
begin
     ClientSocket1.Active:=false;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  fsData : TFileStream;
  sBuffer : String;
begin
  fsData := TFileStream.Create('datei\bindif.exe',fmOpenWrite);
  try
    sBuffer := StringOfChar(#23,Socket.ReceiveLength);
    if Socket.ReceiveBuf(sBuffer[1],Socket.ReceiveLength) <> -1 then
    begin
      fsData.Seek(0, SoFromEnd); //Hier scheint irgendwie noch ein
                                 //Problem aufzutreten
      fsData.Write(sBuffer[1],length(sBuffer));
      Events.Lines.Add('Datenblock empfangen');
    end;    
  finally
    FreeAndNil(fsData);
  end;
end;

Evilboyz 30. Jan 2003 13:52

So, wunderschönen guten Tag Euch allen :mrgreen:
Es funktioniert nun tatsächlich!
Ich sende meinen FileStream jetzt per SendStream:
Code:
fsWork := TFileStream.Create('datei\bindif.exe', fmOpenRead);
sBuffer := StringOfChar(#0,fsWork.Size);
fsWork.Seek(0, soFromBeginning);
Socket.SendStream(fsWork);
Empfangen tue ich das ganz primitiv über ReceiveText:
Code:
sBuffer := Socket.ReceiveText;
fsData.Write(sBuffer[1],Length(sBuffer));
Da das ganze tatsächlich so einfach funktioniert, stelle ich mir natürlich die Frage, ob ich irgendwas noch nicht bedacht habe. Spricht irgendetwas gegen diese Vorgehensweise?
Natürlich ist mir immer noch nicht klar, warum die andere Variante nicht funktioniert hat und da ich ein wissbegieriger Mensch bin, würde mich das trotzdem noch interessieren ....
In jedem Fall: Danke mal für Eure Hilfe ... :spin:

Jan 30. Jan 2003 16:16

Hallo evilboyz,
warum initialisierst du denn beim sender eigentlich noch den Buffer? Den brauchst du doch nichtmehr. Könntest du vielleicht mal den kompletten qtext von dir hier zeigen, vielleicht als attachment wenn er sonst zu lang ist. Ich komme bei mir einfach nichtmehr weiter. Wenn ich den Server schliesse, also quasi ins nimmerland schicke, dann bekomme ich keinen error beim sender, aber wenn ich den server laufen lasse, dann kommt beim server etwas an, aber der sender bekommt eine errormessage.

Kannst du mir mal sagen, warum du den server senden lässt und den client empfangen? normalerweise geht sowas andersrum. Deswegen komme ich auch mit deinen events nicht so ganz zurecht.
So long
Jan

Evilboyz 30. Jan 2003 17:58

hi Jan,

der Server sendet in meinem Fall eine Datei als Antwort auf eine Clientanfrage. Den Code kann ich Dir morgen früh posten, da ich ihn gerade nicht hier habe, sind aber echt auch nur noch 3 oder 4 Zeilen (siehe letzter Beitrag).
Den Verbindungsaufbau mache ich ganz standardmäßig, indem ich einfach .active auf true setze und vorher die Werte für Port und IP zuweise.
Testest Du das ganze eigentlich lokal oder direkt schon übers Netz? Ich hatte nämlich bisher relativ viele Probleme mit Firewalleinstellungen und ich könnte mir vorstellen, dass sich in einem solchen Fall das Programm mit einem Fehler verabschiedet!
Aber wie gesagt, wenn es bei Dir bis morgen nicht läuft, kann ich Dir den Code nochmal geben.

Jan 30. Jan 2003 18:24

Hallo evil,
ich teste das lokal(127.0.0.1).
Und ich brauch echt morgen dann mal deinen code. Weil ich am verzweifeln bin, es wird immer nur eine 4k grosse datei geschrieben, und wenn ich den stream beim sender freigebe dann sifft das tool.
Alles sehr seltsam.
BB
Jan

Evilboyz 31. Jan 2003 08:28

Hi,

ich vermute mal stark, dass Du vergessen hast, den Zeiger des Dateistreams auf die letzte Position zu setzen, dann schreibt er nämlich immer von erster Stelle und kommt nie über 4 KB.

Sender:
Code:
unit Client_Server;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ScktComp, ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    ServerSocket: TServerSocket;
 [...]
    procedure ConnectClick(Sender: TObject);
    procedure DisconnectClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
     Events.Lines.Add('Client Connectet');
     Clients.Text := IntToStr(StrToInt(Clients.Text)+1);
end;

procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
     Events.Lines.Add('Client Disconnected');
     Clients.Text := IntToStr(StrToInt(Clients.Text)-1);
end;

procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var fsWork : TFileStream;
      sIncome : String;
begin
     // Anfrage von Client annehmen
     sIncome := Socket.ReceiveText;

     if sIncome='GetFile' then begin
          // Datei in Stream laden
          fsWork := TFileStream.Create('datei\bindif.exe', fmOpenRead);
          fsWork.Seek(0, soFromBeginning);
          // Stream als Antwort an Client senden
          if Socket.SendStream(fsWork) then begin
             Events.Lines.Add('Datei wurde erfolgreich an Client übertragen');
          end else
              Events.Lines.Add('Ein Fehler ist aufgetreten, die Datei konnte nicht gesendet werden');
     end
     else begin
          Events.Lines.Add(sIncome);
     end;
end;

procedure TForm1.ConnectClick(Sender: TObject);
begin
     ServerSocket.Port := StrToInt(Port.Text); //Festlegung des Ports
     ServerSocket.active := true; //Aktivierung der ServerSocket
     Events.Lines.Add('Server connected on Port ' + Port.Text);
     PageControl.ActivePage := TabSheet1;
end;

procedure TForm1.DisconnectClick(Sender: TObject);
begin
     ServerSocket.active:=false;
     Events.Lines.Add('Server disconnected');
     Clients.Text := '0';
end;

end.
Empfänger:
Code:
unit Client_Server;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ScktComp;

type
  TForm1 = class(TForm)
    Eingabe: TEdit;
    Button: TButton;
    ClientSocket1: TClientSocket;
    Eventlog: TGroupBox;
 [...]
TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ButtonClick(Sender: TObject);
begin
     if ClientSocket1.Active then
        ClientSocket1.Socket.SendText(Eingabe.text);
end;

procedure TForm1.ConnectClick(Sender: TObject);
begin
    ClientSocket1.Port := StrToInt(Port.Text); //Festlegung des Ports
    ClientSocket1.Host := Host.Text; //IP des Zielrechners
    ClientSocket1.active := true; //Aufbau der Verbindung

procedure TForm1.DisconnectClick(Sender: TObject);
begin
     ClientSocket1.Active:=false;
     Events.Lines.Add('Disconnected');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  fsData : TFileStream;
  sBuffer : String;
begin
  // FileStream zum Schreiben öffnen
  fsData := TFileStream.Create('datei\bindif.exe',fmOpenWrite);
  sBuffer := StringOfChar(#00,fsData.Size);
  try
      // Dateiinhalt als String empfangen und in Datei schreiben
      sBuffer := Socket.ReceiveText;
      fsData.Seek(0, SoFromEnd);
      fsData.Write(sBuffer[1],Length(sBuffer));
      Events.Lines.Add('Datenblock empfangen');
  finally
      FreeAndNil(fsData);
  end;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  fsEmpty : TFileStream;
begin
  if FileExists('datei\bindif.exe') then
     DeleteFile('datei\bindif.exe');
  fsEmpty := TFileStream.Create('datei\bindif.exe',fmCreate);
  fsEmpty.Free;
end;

end.

Bonestorm 4. Nov 2003 15:51

Re: beliebige Datei in Stream speichern
 
Hallo zusammen!
Ich finde den Buffer als string zu definieren ist nicht grade die eleganteste Lösung.
Da wird es bei größeren Dateien Probleme geben.
Mein Vorschlag:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  str : TFileStream;
  buffer : Pointer;
begin
  try
    str := TFileStream.Create('xxx.txt',fmOpenRead);
    buffer := AllocMem(str.Size);
    str.Read(Buffer^,str.Size);
    Server.Socket.Connections[0].SendBuf(buffer^,str.Size);
  finally
    FreeMem(buffer);
    FreeAndNil(str);
  end;
end;

procedure TForm1.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  len : integer;
  buffer : Pointer;
  str : TFileStream;
begin
  len := Socket.ReceiveLength;
  try
    str := TFileStream.Create('xxx2.txt',fmCreate);
    buffer := AllocMem(len);
    Socket.ReceiveBuf(buffer^,len);
    str.Write(buffer^,len);
  finally
    FreeAndNil(str);
    FreeMem(buffer);
  end;
end;
Ich denke, dass es so funktionieren müsste.

Christian Seehase 4. Nov 2003 19:20

Re: beliebige Datei in Stream speichern
 
Moin Bonestorm,

was verstehst Du in diesem Zusammenhang unter "grössere Datei"?


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:08 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