2011-08-12 10 views
2

私はZipFileを持っていて、その中の各エントリのオフセット/サイズで配列を作成したいと思います。これは、C++層(JNI)がこれらのサブファイルを抽出せずに直接読み取ることができるようにするためです。JavaでZipFileエントリのファイルオフセットを見つける方法はありますか?

私はファイルの圧縮されたサイズをentry.getCompressedSize()を使用して取得できますが、zip内のファイルのオフセットを見つけるための何も表示されません。

Enumeration<? extends ZipEntry> zipEntries = zipFile.entries(); 
while (zipEntries.hasMoreElements()) 
{ 
    ZipEntry zip = (ZipEntry)zipEntries.nextElement(); 
    //long offset = ? 
    long fileSize = zip.getCompressedSize(); 
} 

これを取得する簡単な方法はありますか?

+0

あなたは本当に解決しようとしている問題は何ですか?全体的にはこれは奇妙な技術的アプローチのように聞こえます。それ以外の方法はわかりません。 –

+0

ネイティブコードをプロジェクト資産に直接アクセスできないAndroid NDK r4を使用して構築されたプロジェクトがあります。オフセット/ファイルサイズをネイティブコードに渡してファイル操作をオーバーライドしてファイルの開始/終了位置を使用してアセットファイルから直接値をロードしました。私が(nda)に入ることができない理由のために、私は今、追加の.zipファイルを読む必要があり、私はこの情報を得るAssetFileDescriptorを持っていません。 –

+0

解決策が見つからない場合は、Javaを使用して解凍して、tempまたは(どこにでもデータを格納しない場合)メモリからファイルコンテンツを提供することができます。 –

答えて

2

ファイル内で発生した順序で.entries()が返すエントリです(実際のファイルまたはヘッダエントリを参照するかどうかは不明です)。これを仮定すると、次のように問題が解決されます:

Enumeration<? extends ZipEntry> zipEntries = zipFile.entries(); 
long offset = 0; 
while (zipEntries.hasMoreElements()) 
{ 
    ZipEntry entry = (ZipEntry)zipEntries.nextElement(); 
    long fileSize = 0; 
    long extra = entry.getExtra() == null ? 0 : entry.getExtra().length; 
    offset += 30 + entry.getName().length() + extra; 
    if(!entry.isDirectory()) 
    { 
     fileSize = entry.getCompressedSize(); 

     // Do stuff here with fileSize & offset 
    }  
    offset += fileSize; 
} 

これは私のケースでは機能しています。ただし、ZIP圧縮仕様によれば、すべてのZIPファイルでは、ファイルがディレクトリ内と全く同じ順序で格納されているわけではありません。私の場合はzipファイルの構築を制御しているので、これは問題ではありませんが、制御されていないソースからzipを操作すると、このアプローチがうまくいかない場合があります。

+0

詳しく説明すると、オフセットは、標準的なZIPヘッダー情報+ファイル名の長さ+いくつかの余分なOS固有のフラグ+データそのものの30バイトで構成されています。 私はバグに遭遇しました。ここでは、Javaが誤ってファイル内にないバイト配列を持つ.getExtra()を返していました。私は私のジッパーのプロセスをコントロールしていたので、正しい値がゼロであることを知っていたので、この用語を削除しました。あなたが似たようなことをしなければならないと分かっている価値があります。 –

関連する問題