[Lazarus] Can't copy TMemoryStream to TProcess.Input
Leonardo M. Ramé
l.rame at griensu.com
Sat Apr 6 16:55:41 CEST 2013
On 2013-04-06 00:04:07 +0200, Mattias Gaertner wrote:
> On Fri, 5 Apr 2013 17:33:22 -0300
> Leonardo M. Ramé <l.rame at griensu.com> wrote:
>
> > Hi, it must be that I've been working for more than 8 hrs but I can't find where the problem is...
> >
> > I need to pass a file via stdIn to TProcess, then capture the StdOut. This
> > program should do what I expect, but, instead it hangs after writing aprox
> > 293000 bytes to Proc.Input stream.
> >
> > Can you take a look at it?.
> >
> > program test;
> >
> > {$mode objfpc}{$H+}
> >
> > uses
> > SysUtils, Classes,
> > process,
> > math;
> >
> >
> > function CompressLZMA(AStream: TMemoryStream): TMemoryStream;
> > var
> > Proc: TProcess;
> > lBuffer: array [0..2048] of byte;
> > ReadCount: integer;
> > lPos: LongInt;
> > begin
> > Result := TMemoryStream.Create;
> > AStream.Position:= 0;
> > writeln('-1-');
> > Proc := TProcess.Create(nil); //Create a new process
> > try
> > Proc.Executable := '/usr/bin/lzma'; //Run lzma
> > Proc.Parameters.Add('--compress');
> > Proc.Options := [poUsePipes, poStderrToOutPut];
> > Proc.Execute;
> >
> > writeln(format('Writing %d bytes...', [AStream.Size]));
> >
> > lPos := 0;
> > while(lPos < AStream.Size) do
> > begin
> > writeln(format('Pos: %d - Size: %d', [lPos, AStream.Size]));
> > ReadCount := AStream.Read(lBuffer, SizeOf(lBuffer));
> > Proc.Input.Write(lBuffer, ReadCount);
> > lPos := lPos + ReadCount;
>
> After every write to Input, read all available from Output and StdErr.
>
> Mattias
>
Thanks Mattias, I went a step further.
Sadly now I'm getting an "unexpected end of input" error when I try to
decompress the generated file using "lzma -d -c output.lzma >
output.dcm".
Attached is the modified program.
Regards,
--
Leonardo M. Ramé
http://leonardorame.blogspot.com
-------------- next part --------------
program test;
{$mode objfpc}{$H+}
uses
SysUtils, Classes,
process,
math;
function CompressLZMA(AStream: TMemoryStream): TMemoryStream;
var
Proc: TProcess;
lBuffer: array [0..2047] of byte;
ReadCount: longint;
WriteCount: longint;
begin
Result := TMemoryStream.Create;
AStream.Position:= 0;
Proc := TProcess.Create(nil);
try
Proc.Executable := '/usr/bin/lzma';
Proc.Parameters.Add('-z');
Proc.Parameters.Add('-c');
Proc.Options := [poUsePipes, poStderrToOutPut];
Proc.Execute;
while(AStream.Position < AStream.Size) do
begin
ReadCount := AStream.Read(lBuffer, SizeOf(lBuffer));
Proc.Input.Write(lBuffer, ReadCount);
while (Proc.Output.NumBytesAvailable > 0) do
begin
WriteCount := Min(SizeOf(lBuffer), Proc.Output.NumBytesAvailable);
Proc.Output.Read(lBuffer, WriteCount);
Result.Write(lBuffer, WriteCount);
end;
end;
Result.Position:= 0;
finally
Proc.Free;
end;
end;
var
lStr: TMemoryStream;
begin
lStr := TMemoryStream.Create;
try
lStr.LoadFromFile('mg.dcm');
CompressLZMA(lStr).SaveToFile('output.lzma');
finally
lStr.Free;
end;
end.
More information about the Lazarus
mailing list