[Lazarus] Can't copy TMemoryStream to TProcess.Input
Leonardo M. Ramé
l.rame at griensu.com
Sat Apr 6 19:48:18 CEST 2013
On 2013-04-06 13:22:39 -0300, Leonardo M. Ramé wrote:
> On 2013-04-06 17:46:06 +0200, Mattias Gaertner wrote:
> > On Sat, 6 Apr 2013 12:37:06 -0300
> > Leonardo M. Ramé <l.rame at griensu.com> wrote:
> >
> > >[...]
> > > > Check return value of Proc.Input.Write.
> > > > And call Proc.CloseInput when your input was written completely.
> > > >
> > > >
> > >
> > > Mmm, I'm getting the same result.
> > >
> > > I attached the new code.
> >
> > When you give Proc.Input.Write 200 bytes and it returns that the other
> > process could only process 100 of them. What bytes do you have to write
> > next?
> >
>
> Sorry, I'm not getting it. Which other process?, apart from that,
> Proc.Input.Write is always returning the sizeof(buffer) except when it
> reaches the end, where it can be less than it.
>
> It seems that the Proc.Input part is ok, aparently the Proc.Output is
> wrong :(
>
> I attached a slightly modified code.
>
Finally got it working, I was forgetting to read the last part of the
Output stream. ...I still don't know why this last chunk of bytes
doesn't show up in NumBytesAvailable.
I attached the code.
Regards,
--
Leonardo M. Ramé
http://leonardorame.blogspot.com
-------------- next part --------------
program test;
{$mode objfpc}{$H+}
uses
SysUtils, Classes,
process,
math;
const
READ_BYTES = 2048;
procedure CompressLZMA(InStream, OutStream: TMemoryStream);
var
Proc: TProcess;
lInBuffer: array [0..2047] of byte;
BytesRead: longint;
NumBytes: longint;
begin
InStream.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;
BytesRead := 0;
repeat
NumBytes := InStream.Read(lInBuffer, SizeOf(lInBuffer));
Proc.Input.Write(lInBuffer, NumBytes);
if InStream.Position >= InStream.Size then
Proc.CloseInput;
while Proc.Output.NumBytesAvailable > 0 do
begin
OutStream.SetSize(BytesRead + READ_BYTES);
NumBytes := Proc.Output.Read((OutStream.Memory + BytesRead)^, READ_BYTES);
if NumBytes > 0
then begin
Inc(BytesRead, NumBytes);
end;
end;
until Proc.Input = nil;
// read the last part
repeat
OutStream.SetSize(BytesRead + READ_BYTES);
NumBytes := Proc.Output.Read((OutStream.Memory + BytesRead)^, READ_BYTES);
if NumBytes > 0 then
Inc(BytesRead, NumBytes);
until NumBytes <= 0;
OutStream.SetSize(BytesRead);
OutStream.Position:= 0;
finally
Proc.Free;
end;
end;
var
lInputStream: TMemoryStream;
lOutputStream: TMemoryStream;
begin
lInputStream := TMemoryStream.Create;
lOutputStream := TMemoryStream.Create;
try
lInputStream.LoadFromFile('mg.dcm');
CompressLZMA(lInputStream, lOutputStream);
lOutputStream.SaveToFile('output.lzma');
finally
lInputStream.Free;
lOutputStream.Free;
end;
end.
More information about the Lazarus
mailing list