7

500 ~ 1000k のエントリを含む 1 ~ 2GB の zip ファイルがあります。完全に解凍せずに、名前でファイルを数秒で取得する必要があります。ファイルが HDD に保存されている場合、これは正常に機能します。

public class ZipMapper {
    private HashMap<String,ZipEntry> map;
    private ZipFile zf;

    public ZipMapper(File file) throws IOException {
        map = new HashMap<>();
        zf = new ZipFile(file);

        Enumeration<? extends ZipEntry> en = zf.entries();
        while(en.hasMoreElements()) {
            ZipEntry ze = en.nextElement();
            map.put(ze.getName(), ze);
        }
    }

    public Node getNode(String key) throws IOException {
        return Node.loadFromStream(zf.getInputStream(map.get(key)));
    }
}

しかし、プログラムが Amazon S3 から zip ファイルをダウンロードし、その InputStream (またはバイト配列) を持っている場合、どうすればよいでしょうか? 1GB のダウンロードには約 1 秒かかりますが、HDD への書き込みには時間がかかる場合があります。また、HDD ガベージ コレクターがないため、複数のファイルを処理するのは少し難しくなります。

ZipInputStream は、エントリへのランダム アクセスを許可しません。

バイト配列でメモリ内に仮想ファイルを作成できればいいのですが、方法が見つかりませんでした。

4

5 に答える 5

2

終了時にファイルを削除するようにマークできます。

インメモリ アプローチを使用する場合: 新しい NIO.2 ファイル API をご覧ください。Oracleはzip / jar用のファイルシステムプロバイダーを提供し、AFAIK ShrinkWrapはメモリ内ファイルシステムを提供します。2 つの組み合わせを試すことができます。

NIO.2 ファイル API (ライブラリはオープン ソースです) を使用して、Zip ファイルとの間でディレクトリとファイルをコピーするユーティリティ メソッドをいくつか作成しました。

メイヴン:

<dependency>  
    <groupId>org.softsmithy.lib</groupId>  
    <artifactId>softsmithy-lib-core</artifactId>  
    <version>0.3</version>  
</dependency>  

チュートリアル:

http://softsmithy.sourceforge.net/lib/current/docs/tutorial/nio-file/index.html

API: CopyFileVisitor.copy

特にPathUtils.resolveは、ファイルシステム全体のパスを解決するのに役立ちます。

于 2013-02-27T13:28:10.713 に答える
1

SecureBlackbox ライブラリを使用できます。これにより、シーク可能なストリームでの ZIP 操作が可能になります。

于 2013-02-27T13:31:26.763 に答える
0

ブラックボックスライブラリには、Extract(String name、String outputPath)メソッドのみがあります。実際、シーク可能なzipストリーム内の任意のファイルにランダムにアクセスできるようですが、結果をバイト配列に書き込んだり、ストリームを返したりすることはできません。

ShrinkWrapのドキュメントが見つかりませんでした。FileSystem/FileSystemProviderなどの適切な実装が見つかりませんでした。

しかし、私が実行しているAmazon EC2インスタンス(大)は、どういうわけか1GBのファイルを約1秒でディスクに書き込みます。そのため、ファイルをディスクに書き込んでZipFileを使用します。

HDDが遅い場合は、RAMディスクが最も簡単な解決策になると思います。

于 2013-02-27T22:28:17.390 に答える
0


「メモリ内」ファイルシステム(つまり、RAMドライブ)を作成するには、OSの使用を検討する必要があると思います。
さらに、FileSystem s API を見てください。

于 2013-02-27T13:29:51.933 に答える
0

完全に異なるアプローチ: サーバーがディスク上にファイルを持っている場合 (そしておそらく既に RAM にキャッシュされている場合): ファイルを直接提供するようにします。つまり、必要なファイルを送信してから、サーバー上でこれらを抽出して配信するように注意してください。

于 2013-02-27T14:36:09.180 に答える