使用 TIdCompressorZLib 压缩 TIdMemoryBufferStream

compressing TIdMemoryBufferStream with TIdCompressorZLib

我问的是压缩 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 然后调用压缩吗?

TIdCompressorZLib 组件仅用于 TIdHTTPTIdFTP 组件的 Compressor 属性。

对于 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;

但是,由于您发送的是压缩数据的字节大小(通过在 TIdIOHandler.Write(TStream) 中将 AWriteByteCount 参数设置为 True),这将不适用于压缩拦截。

Indy 的 IdZLib 单元有一个 TCompressionStream class 和各种 ...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;