我可以使用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;
只需使用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;