用ZLIB压缩到字节数组吗?

问题描述 投票:0回答:1

我可以使用ZLIB(带有ZLIB头的Deflate)以某种方式用Delphi压缩并获得字节数组吗?

现在我正在从TMemoryStream复制,但是最好不要复制回数组(这样总体上更快)

  PackedStream := TMemoryStream.Create;
  ZLib := TZCompressionStream.Create(PackedStream);
  ZLib.WriteBuffer(UnpackedArray[0], UnpackedArrayLen);
  ZLib.Free;

  PackedArrayLen := PackedStream.Size;
  SetLength(PackedArray, PackedArrayLen);
  PackedStream.Position := 0;
  PackedStream.Read(PackedArray[0], PackedArrayLen);
  PackedStream.Free;
delphi zlib delphi-rio
1个回答
0
投票

只需使用TMemoryStream.Memory 作为字节数组,只是在使用完字节之后才释放流:

PackedStream := TMemoryStream.Create;
try
  ZLib := TZCompressionStream.Create(PackedStream);
  try
    ZLib.WriteBuffer(UnpackedArray[0], UnpackedArrayLen);
  finally
    ZLib.Free;
  end;
  // use PByte(PackedStream.Memory) up to PackedStream.Size bytes as needed...
finally
  PackedStream.Free;
end;

否则,您可以使用TBytesStream代替TMemoryStream

PackedStream := TBytesStream.Create;
try
  ZLib := TZCompressionStream.Create(PackedStream);
  try
    ZLib.WriteBuffer(UnpackedArray[0], UnpackedArrayLen);
  finally
    ZLib.Free;
  end;
  // use PackedStream.Bytes up to PackedStream.Size bytes as needed...
finally
  PackedStream.Free;
end;

或者,如果您有一个预分配的字节数组,则可以使用TCustomMemoryStream给它提供指向该数组的指针,以便它将直接写入该数组:

type
  TMemoryBufferStream = class(TCustomMemoryStream)
  public
    constructor Create(APtr: Pointer; ASize: NativeInt);
    function Write(const Buffer; Count: Longint): Longint; override;
  end;

constructor TMemoryBufferStream.Create(APtr: Pointer; ASize: NativeInt);
begin
  inherited Create;
  SetPointer(APtr, ASize);
end;

function TMemoryBufferStream.Write(const Buffer; Count: Longint): Longint;
var
  LAvailable: Int64;
  LNumToCopy: Longint;
begin
  Result := 0;
  LAvailable := Size - Position;
  if LAvailable > 0 then
  begin
    LNumToCopy := Count;
    if LNumToCopy > LAvailable then
      LNumToCopy := Longint(LAvailable);
    if LNumToCopy > 0 then
    begin
      Move(Buffer, (PByte(Memory) + Position)^, LNumToCopy);
      Seek(LNumToCopy, soCurrent);
      Result := LNumToCopy;
    end;
  end;
end;

PackedStream := TMemoryBufferStream.Create(SomeBuffer, BufferSize);
try
  ZLib := TZCompressionStream.Create(PackedStream);
  try
    ZLib.WriteBuffer(UnpackedArray[0], UnpackedArrayLen);
  finally
    ZLib.Free;
  end;
  // use SomeBuffer up to PackedStream.Size bytes as needed...
finally
  PackedStream.Free;
end;
© www.soinside.com 2019 - 2024. All rights reserved.