Zipファイルから無圧縮ファイルをStreamに展開するには?

解決


Alpha  2014-02-11 21:01:38  No: 46022  IP: 192.*.*.*

初めまして。
XE4+FMXでTZipfileを使い、Zipファイルから特定ファイルをTStreamへ
展開できないか試しています。

Extractでファイル名を指定して直接ファイル書き出しは出来ますが、
Readを使ってStreamに書き出す際に不具合が発生します。

コードとしては
var
  LStream     : TStream;
  LZipFile    : TZipFile;
  LocalHeader : TZipHeader;
  MemoryStream: TMemoryStream;
begin

  LZipFile := TZipFile.Create;
  LZipFile.Open( 'TestZip.zip' , zmRead);

  LStream      := TStream.Create;
  LZipFile.Read('data.bin', LStream, LocalHeader);

  MemoryStream := TMemoryStream.Create;
  MemoryStream.CopyFrom( LStream, 0 );
  MemoryStream.SaveToFile( 'ExtractData.bin' );
  MemoryStream.Free;

  LZipFile.Free;

end;


取り出したいファイルの圧縮方法が、
"Deflate" の場合:正常に指定ファイルを書き出す。
"Stored (無圧縮)" の場合:Zipファイル全体を書き出す。
ようです。

こういった場合、圧縮方法をチェックし、Storedだった場合は別途処理を
行う必要があるのでしょうか?

編集 削除
monaa  2014-02-13 00:10:58  No: 46023  IP: 192.*.*.*

ソースを全部チェックしたわけでは無いのでなんとも言えませんし、
圧縮ソフトによる違いがあるかもしれませんが
Lhaplusの無圧縮zipからのストリームへの読み込み動作は確認しました。
XE2+VCL
TFeZipFile = class(TZipFileEx)<-DekoさんのHP参照です。
procedure TFeZipFile.GetStream(aStream: TStream; aIndex: Integer);
var
  aInStream:TMemoryStream;
  aLH:TZipHeader;
begin
  aInStream := TMemoryStream.Create;
  Read(aIndex,TStream(aInStream),aLH);
  aStream.CopyFrom(aInStream, FileInfo[aIndex].UncompressedSize);
  aInStream.Free;
end;

編集 削除
Alpha  2014-02-14 02:38:11  No: 46024  IP: 192.*.*.*

>>monaaさん
検証ありがとうございます。
こちらでも試してみた結果、無圧縮時のファイルサイズをLocalHeaderから
無圧縮時のファイルサイズを取得しCopyFromで同じ値を設定すれば、
元のコードでもうまくいきました。

圧縮ファイルの場合はCopyFromで0を指定してもうまくいっていたので、
そのままいけるのかと思っていました。
もちょっと検証すればよかったですね…

編集 削除