Delphi 使用TIdCompressorLib解压gzip文件

Delphi 使用TIdCompressorLib解压gzip文件,delphi,indy,Delphi,Indy,我使用德尔福2007与印地10。我有一个gzip文件。我已经验证了它可以用这个解压 我正在尝试使用TIdCompressorZlib组件使用Delphi进行解压缩。这是我的密码: procedure TForm2.Button9Click(Sender: TObject); var lCompressor : TIdCompressorZLib; FileStream : TFileStream; memorystream: TMemoryStream; begin lCompr

我使用德尔福2007与印地10。我有一个gzip文件。我已经验证了它可以用这个解压

我正在尝试使用TIdCompressorZlib组件使用Delphi进行解压缩。这是我的密码:

procedure TForm2.Button9Click(Sender: TObject);
var
  lCompressor : TIdCompressorZLib;
  FileStream : TFileStream;
  memorystream: TMemoryStream;
begin
  lCompressor := TIdCompressorZLib.create(self);
  FileStream := TFileStream.Create('c:\temp\test.gz', fmOpenRead);
  filestream.position := 0;
  memorystream:= TMemoryStream.create;
  memorystream.position := 0;
  lcompressor.DecompressGZipStream(FileStream,MemoryStream);
  filestream.free;
  showmessage('done');
end;
我不能让它工作。如果我在构造函数中传递了fmOpenReadWrite,则调用decompressgzip流时会出现zlib错误(-5)

如果我在构造函数中通过了fmOpenRead,则在调用DecompressGZipStream时会得到一个操作系统错误代码5拒绝访问

更新David Hefferan建议这是一个文件读取问题。所以我把注意力集中在这一点上。我可以使用以下步骤复制文件:

Procedure FileCopy( Const sourcefilename, targetfilename: String );
Var
 S, T: TFileStream;
Begin
 S := TFileStream.Create( sourcefilename, fmOpenRead );
 try
   T := TFileStream.Create( targetfilename,
                            fmOpenWrite or fmCreate );
   try
     T.CopyFrom(S, S.Size ) ;
   finally
     T.Free;
   end;
 finally
   S.Free;
 end;
 showmessage('done');
End;
UPD根据David Heffernan的说法,我已经确认我可以读取数据。我通过以下函数成功地运行了该文件。它返回正确的字符数(字节):

函数GetTextFromFile(AFile:string;var Returnstring:string):布尔; 变量 FileStream:TFileStream; 开始 结果:=假; 如果文件不存在(文件),则退出; FileStream:=TFileStream.Create(文件,fmOpenRead); 尝试 如果FileStream.Size为0,则 开始 SetLength(Returnstring,FileStream.Size); 读取(返回字符串[1],FileStream.Size); 结果:=真; 终止 最后 免费文件流; 终止 终止
您可以尝试使用Delphi
zlib
单元来解压缩gzip

示例代码:

procedure TForm2.Button9Click(Sender: TObject);
var
  DecompressionStream : TDecompressionStream;
  FileStream : TFileStream;
  dest: TFileStream;
  byteCount: Integer;
  buffer: array [0..65535] of Byte;
begin
  FileStream := TFileStream.Create('c:\temp\test.gz', fmOpenRead);
  try
    //no need to set FileStream position to 0, it's there already

    DecompressionStream:=TDecompressionStream.Create(FileStream, 15+16);

    //16 is flag that gzip stream used, not zlib.
    //15 is maximum memory usage, to speed-up decompression. 
    try
      dest:=TFileStream.Create('c:\temp\test.txt', fmCreate);
      try
        dest.CopyFrom(DecompressionStream,0);
      finally
        dest.free;
      end;
    finally
      DecompressionStream.free;
    end;
  finally
    filestream.free;
  end;
  showmessage('done');
end;

UPD:此代码不适用于D2007或更早版本,没有带WindowBits参数的重载构造函数

拒绝访问错误代码5不明确。将zlib放在一边,尝试读取文件流。你也会犯同样的错误吗。至于读/写,你为什么要写呢?不要按照你的意思“把zlib放在一边”。你的意思是“把压缩放在一边-你能读文件吗”?至于“你为什么要写”——不,我不想写同一个文件。我只是在试验。并通过更改TFileStream open属性发现情况发生了变化。我将验证我是否可以读取该文件。最后,我只需要一个简单的例程来获取gz文件并将其解压缩为文本。错误表明您无法读取该文件。因为访问被拒绝。这就不是zlib的问题了。试着从文件流中读取。这并不能完全回答您的问题,仅供参考:Delphi zlib单元能够压缩/解压gzip文件。通常它处理zlib流(实际上没有头),但如果您使用WindowBits=15+16的构造函数版本,它会。16(或者我们应该说,第4位)意味着使用gzip头,15对于WindowBits本身来说是一个很好的值。@YuriyAfanasenkov-好-将尝试一下。我看到system.zlib.dcu。但是没有pas文件,因此我可以查看可用的方法。你能提供一个简单的例子吗?顺便说一句,我使用的是Delphi2007。在尝试此操作时,TDecompressionStream.Create的第二个参数出现编译错误;它只接受第一个文件流(记住D2007)。抑制第二个参数编译。但随后它在解压流程中抛出了一个“错误”(仅此而已)。Read@MSchenkel可能这项功能是在以后的版本中添加的。。。有趣的是,我基于zlib编写了自己的TGZipDecompressionStream。可以在这里共享,没有多少。@MSchenkel通过继承TCompressionStream/TDecompressionStream将gzip功能添加到D2009 zlib需要2行代码,但他们将一些字段设置为私有,这需要复制粘贴一些代码(不超过50行)。
procedure TForm2.Button9Click(Sender: TObject);
var
  DecompressionStream : TDecompressionStream;
  FileStream : TFileStream;
  dest: TFileStream;
  byteCount: Integer;
  buffer: array [0..65535] of Byte;
begin
  FileStream := TFileStream.Create('c:\temp\test.gz', fmOpenRead);
  try
    //no need to set FileStream position to 0, it's there already

    DecompressionStream:=TDecompressionStream.Create(FileStream, 15+16);

    //16 is flag that gzip stream used, not zlib.
    //15 is maximum memory usage, to speed-up decompression. 
    try
      dest:=TFileStream.Create('c:\temp\test.txt', fmCreate);
      try
        dest.CopyFrom(DecompressionStream,0);
      finally
        dest.free;
      end;
    finally
      DecompressionStream.free;
    end;
  finally
    filestream.free;
  end;
  showmessage('done');
end;