初めまして。
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だった場合は別途処理を
行う必要があるのでしょうか?
ソースを全部チェックしたわけでは無いのでなんとも言えませんし、
圧縮ソフトによる違いがあるかもしれませんが
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;
>>monaaさん
検証ありがとうございます。
こちらでも試してみた結果、無圧縮時のファイルサイズをLocalHeaderから
無圧縮時のファイルサイズを取得しCopyFromで同じ値を設定すれば、
元のコードでもうまくいきました。
圧縮ファイルの場合はCopyFromで0を指定してもうまくいっていたので、
そのままいけるのかと思っていました。
もちょっと検証すればよかったですね…
ツイート | ![]() |