Problem mit Auslesen von TMemoryStream

Antworten
Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Problem mit Auslesen von TMemoryStream

Beitrag von Targion »

Hallo!
Ich stelle diese Frage euch, sonst werde ich hier gleich verrückt! Vermutlich ist die Lösung einfach, aber ich habe halt noch nicht so oft mit Streams gearbeitet.
Folgendes problem: So lese ich den Inhalt eines TProcess-Outputs aus:

Code: Alles auswählen

const READ_BYTES = 2048;
M := TMemoryStream.Create;
 m.Clear;
   BytesRead := 0;
   while P.Running do
   begin
     // make sure we have room
     M.SetSize(BytesRead + READ_BYTES);
     // try reading it
     n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
     if n > 0
     then begin
       Inc(BytesRead, n);
       write(PAnsiChar(m.Memory));
     end
     else begin
       // no data, wait 100 ms
       Sleep(100);
     end;
   end;
   // read last part
   repeat
     // make sure we have room
     M.SetSize(BytesRead + READ_BYTES);
     // try reading it
     n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
     if n > 0
     then begin
       Inc(BytesRead, n);
       writeLn(PAnsiChar(m.Memory));
     end;
   until n <= 0;
   p.free;
   M.Free;
p ist ein TProcess und s ein String. Der Output wird auch so ausgegeben, ABER: Zwischen den einzelnen Zeilen von korrektem Output und vor allem am Ende werden immer wieder Zeilen einer zuvor erstellten, aber wieder Freigegebenen StringList eingestreut. Wie kann das sein? Greife ich da auf alten Speichermüll zu?

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem mit Auslesen von TMemoryStream

Beitrag von theo »

Das Problem liegt wahrsch hier:
write(PAnsiChar(m.Memory));

Während du am Offset schreibst ((M.Memory + BytesRead)^), gibst du immer wieder den ganzen Inhalt vom Anfang des m.Memory aus (Der Zeiger bleibt ja konstant).
Ausserdem bin ich nicht ganz sicher, ob ein simpler Typecast PAnsiChar(m.Memory) hier das terminating null reinschreibt.

Probier mal sowas: SetString(AAnsiString, PChar(M.Memory), M.Size); //Das erste Problem ist hier nicht gelöst.

Also insg. wahrsch. so
SetString(AAnsiString, PChar(M.Memory + BytesRead), n);
Write(AAnsiString);

Nicht getestet.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: Problem mit Auslesen von TMemoryStream

Beitrag von Targion »

So habe ich das auch erst gemacht. Mit dieser Methode wird erstmal der komplette Inhalt der alten StringList ausgegeben und dann die neuen Outputs. Mit der hier vorher angegebenen Methode werden die Strings nur eingestreut.

EDIT: Komisch, jetzt läuft's auf einmal... Waren wohl noch alte ppus vorhanden... Ich habe einfach nur den Stream vorher löschen müssen, und jetzt läuft's!
Danke für die Hilfe!

Antworten