我在使用Delphi中的ZLib单元进行解压缩时遇到了一个小问题。
现在我可以使用TZZipCompression类完美地压缩和解压缩.zip文件(它不会打开为zip文件,但它确实可以解压缩回原始文件,我可以打开并编辑)。
我也可以使用TZGZipCompression类很好地压缩为.gz文件(有趣的是,我可以完美地打开这个gzip文件)。
然而我的问题是它无法从.gz文件解压缩,并且一旦它到达就会抛出错误。
有趣的是,帮助文件中的示例如下:
但是这也不起作用。 有人能发现问题吗?
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变量传入和传出。
我编写了代码,使其能够执行两种类型的压缩,标准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)
但是这也不起作用。 有人能发现问题吗?