【发布时间】:2016-12-06 17:34:27
【问题描述】:
我在使用 Delphi 中的 ZLib 单元解压缩时遇到了一个小问题
unit uZCompression;
interface
uses
uCompression;
type
TZZipCompression = class(TInterfacedObject, ICompression)
public
function DoCompression(aContent: TArray<Byte>): TArray<Byte>;
function DoDecompression(aContent: TArray<Byte>): TArray<Byte>;
function GetWindowsBits: Integer; virtual;
end;
TZGZipCompression = class(TZZipCompression)
function GetWindowsBits: Integer; override;
end;
implementation
uses
System.ZLib, System.Classes, uMxKxUtils;
{ TZCompression }
function TZZipCompression.DoCompression(aContent: TArray<Byte>): TArray<Byte>;
var
LContentStream, LOutputStream: TMemoryStream;
LCompressedStream: TZCompressionStream;
begin
LContentStream := ByteArrayToStream(aContent);
LOutputStream := TMemoryStream.Create;
LCompressedStream := TZCompressionStream.Create(LOutputStream, zcDefault, GetWindowsBits);
LCompressedStream.CopyFrom(LContentStream, LContentStream.Size);
LCompressedStream.Free;
Result := StreamToByteArray(LOutputStream);
LOutputStream.Free;
LContentStream.Free;
end;
function TZZipCompression.DoDecompression(aContent: TArray<Byte>): TArray<Byte>;
var
LContentStream, LOutputStream: TMemoryStream;
LDecompressedStream: TZDecompressionStream;
begin
LContentStream := ByteArrayToStream(aContent);
LOutputStream := TMemoryStream.Create;
LDecompressedStream := TZDecompressionStream.Create(LContentStream);
LOutputStream.CopyFrom(LDecompressedStream, LDecompressedStream.Size);
LDecompressedStream.Free;
Result := StreamToByteArray(LOutputStream);
LOutputStream.Free;
LContentStream.Free;
end;
function TZZipCompression.GetWindowsBits: Integer;
begin
Result := 15;
end;
{ TZGZipCompression }
function TZGZipCompression.GetWindowsBits: Integer;
begin
Result := inherited;
Result := Result + 16;
end;
end.
这是我的单元,由接口驱动(你不需要知道),数据通过 TArray 变量传入和传出。
我将它编码为能够进行 2 种类型的压缩,标准 zip 和 gzip,这由传入函数的 windowsbits 决定。
这里有几个用于将 TArray 转换为 TMemoryStream 的其他函数
function ByteArrayToStream(aContent: TArray<Byte>): TMemoryStream;
begin
Result := TMemoryStream.Create;
Result.Write(aContent, length(aContent)*SizeOf(aContent[0]));
Result.Position := 0;
end;
function StreamToByteArray(aStream: TMemoryStream): TArray<Byte>;
var
LStreamPos: Int64;
begin
if Assigned(aStream) then
begin
LStreamPos := aStream.Position;
aStream.Position := 0;
SetLength(Result, aStream.Size);
aStream.Read(Result, aStream.Size);
aStream.Position := LStreamPos;
end
else
SetLength(Result, 0);
end;
现在我可以使用 TZZipCompression 类完美地压缩和解压缩为 .zip(它不会以 zip 文件的形式打开,但它会解压缩回我可以打开和编辑的原始文件)。
我也可以使用 TZGZipCompression 类很好地压缩到 .gz(有趣的是,我可以很好地打开这个 gzip 文件)。
但是我的问题是它不会从 .gz 文件中解压缩回来,并且一旦命中就会抛出错误
LOutputStream.CopyFrom(LDecompressedStream, LDecompressedStream.Size)
有趣的是,帮助文件示例如下所示
LOutputStream.CopyFrom(LDecompressedStream, 0)
但这也不起作用。
谁能发现问题?
【问题讨论】:
标签: delphi zlib delphi-10.1-berlin