使用TIdCompressorZLib压缩TIdMemoryBufferStream

时间:2017-03-14 17:13:30

标签: indy indy10

我在询问是否有可能压缩TIdMemoryBufferStream使用TIdCompressorZLib如何使用以下代码正确完成

procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
Var
Strm: TIdMemoryBufferStream;
IdCompressorZLib : TIdCompressorZLib;
begin

Strm := TIdMemoryBufferStream.Create(PByte(Buffer), BufferSize);
IdCompressorZLib := TIdCompressorZLib.Create(nil);
try
// then can't figure what the right process to do 
FTCP.Socket.WriteLn('Stream');
FTCP.Socket.LargeStream := True;
FTCP.Socket.Write(Strm, 0, True);
finally
FreeAndNil(Strm);
FreeAndNil(IdCompressorZLib);
end;

end;

我不确定需要完成的正确流程

作为示例我应该创建另一个变量StrmB然后调用压缩它吗?

1 个答案:

答案 0 :(得分:1)

TIdCompressorZLib组件仅用于CompressorTIdHTTP组件的TIdFTP属性。

对于通过TCP连接的通用压缩,您可以将TIdCompressionIntercept组件分配给TCP连接的IOHandler.Intercept属性,例如:

var
  Compressor : TIdCompressionIntercept;
begin
  Compressor := TIdCompressionIntercept.Create(nil);
  try
    Compressor.CompressionLevel := 9;
    FTCP.Socket.Intercept := Compressor;
    try
      // any data written here will be compressed....
    finally
      FTCP.Socket.Intercept := nil;
    end;
  finally
    Compressor.Free;
  end;
end;

但是,由于您要发送压缩数据的字节大小(通过在AWriteByteCount中将TIdIOHandler.Write(TStream)参数设置为True),因此无法使用压缩截距。

Indy的IdZLib单元有一个TCompressionStream类和各种...CompressStream/Ex()函数,您可以使用它们,例如:

procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
var
  Strm: TMemoryStream;
  Compressor : TCompressionStream;
begin
  Strm := TMemoryStream.Create;
  try
    Compressor := TCompressionStream.Create(clMax, Strm, False);
    try
      WriteTIdBytesToStream(Compressor, Buffer, BufferSize);
    finally
      Compressor.Free;
    end;

    FTCP.Socket.WriteLn('Stream');
    FTCP.Socket.LargeStream := True;
    FTCP.Socket.Write(Strm, 0, True);
  finally
    Strm.Free;
  end;
end;

或者:

procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
var
  InStrm: TIdMemoryBufferStream;
  OutStrm: TMemoryStream;
begin
  OutStrm := TMemoryStream.Create;
  try
    InStrm := TIdMemoryBufferStream.Create(PByte(Buffer), BufferSize);
    try
      CompressStreamEx(InStrm, OutStrm, clMax, zsZLib);
    finally
      InStrm.Free;
    end;

    FTCP.Socket.WriteLn('Stream');
    FTCP.Socket.LargeStream := True;
    FTCP.Socket.Write(OutStrm, 0, True);
  finally
    OutStrm.Free;
  end;
end;