1

背景
現在、HTTP サーブレットを介して HTTP リクエストで zip ファイルを取得しようとしています。受信した zip ファイルには、3 つの異なるファイルが含まれています。これらのファイルにはフィルターで除外したい情報が含まれており、ソースからこれを行うことはオプションではありません (その方がはるかに優れていることはわかっていますが)。

ファイルが最初からビルドされているソースからファイル内の一部の情報を除外できないため、私の解決策は、ファイルを解凍し、これら 3 つのファイルを文字列として読み取ってからフィルター処理することです。最後に、すべてを「zipfile」(inputStream) として「再構築」し、inputStream を返します。

問題
現在、ファイルの解凍とフィルタリングを処理するクラスを作成しました。最後に、zip ファイルと 3 つのファイルを含む新しい inputStream を返したいだけです。

HTTPエンティティからコンテンツをinputStreamに取得し、このinputStreamを解凍して、3つのファイルを3つの文字列として取得するところまで来ました。これが機能するかどうかを確認するために、現在、それらを解凍してinputStreamを閉じて返すだけではやりたくありません。ただし、inputStreamを返すと例外が発生します。

 java.io.IOException: Attempted read on closed stream.

これは、inputStream が以下に示す関数の外部で使用されるためです。zipInputStream を閉じると、おそらく、さらに作業を進めるために inputStream も閉じます。

現在のコード

public InputStream convertInputStream(HttpEntity entity)
{
    InputStream inputStream = null;
    try
    {
        inputStream = entity.getContent();
    }
    catch (IOException e11)
    {

    }

    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    Vector <String>entryVector = new Vector<String>();
    ZipEntry entry;
    try
    {
        String entryValue;
        while((entry = zipInputStream.getNextEntry()) != null)
        {           
            System.out.println("Unzipping file: " + entry.getName() + "...");
            byte [] buf = new byte[(int) entry.getSize()];
            zipInputStream.read(buf);
            entryValue = new String(buf);
            entryVector.add(entryValue);
            zipInputStream.closeEntry();
        }
    }
    catch(IOException e)
    {
        System.out.println("error in getting next entry.");
    }
    finally
    {
        try 
        {
            zipInputStream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        System.out.println("Unzipping done!");
    }
    return inputStream;
}

これをできるだけ明確に表現できればと思います。この関数の外にソリューション全体を表示できない場合、これを理解するのが非常に混乱していることは今でもわかります。

4

4 に答える 4

2

「解凍ファイル」を印刷する場合、実際には何も解凍していません。これを行う場合は、read()関数を使用してZipInputStreamからエントリのコンテンツを読み取り、それをファイルに書き込む必要があります。

編集:(圧縮された)zipファイルを入力ストリームからバイト配列に読み込んでみることができます。次に、その配列にByteArrayInputStreamを作成し、ZipInputStreamをその配列にラップします。次に、基になるストリームを閉じずに、入力ストリームを安全に閉じることができます。

また、文字列としてのファイルの内容が実際に役立つことを確認してください。new String(byte [])は、デフォルトのエンコーディングを使用して文字列を作成するため、これは非常に役に立たない可能性があります。

于 2010-07-08T08:56:09.697 に答える
1

それで、あなたはネットワークを介して「ダウンロード」していませんか?ダウンロードとは、ファイルをzipアーカイブからローカルハードディスクに解凍することを意味しますか?

次の方法でzipファイルを簡単に解凍できます。

    private static File unZipFile(File zipFileIn) throws Exception {
        ZipFile unZipFile = new ZipFile(zipFileIn);
        Enumeration<? extends ZipEntry> entries = unZipFile.entries();
        String topFile = null;
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                // Assume directories are stored parents first then children
                String extractFile = entry.getName();
                if (topFile == null) {
                    topFile = extractFile;
                }
                // This is not robust, just a quick solution
                (new File(entry.getName())).mkdir();
                continue;
            }
            copyInputStream(unZipFile.getInputStream(entry),new BufferedOutp    utStream(new FileOutputStream(entry.getName())));
        }
        unZipFile.close();
        File newFile = new File(zipFileIn.getParentFile().getAbsoluteFile(),topFile);
        return newFile;
    }

    private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
            while((len = in.read(buffer)) >= 0)
            out.write(buffer, 0, len);
            in.close();
        out.close();
    }

このメソッドは、解凍されたファイルのルートであるファイルを返します。

おそらく、あなたが何をしようとしているのかについて、より詳細に質問するのは良い考えでしょう。ATMの誰もが、ソリューションに取り組む代わりに、あなたが何をしようとしているのかを推測しています。

于 2010-07-08T09:23:39.313 に答える
0

バイナリと解凍された形式で同時に保存しながら、zipファイルをダウンロードしようとしているようです。その場合は、最初にバイナリ形式でダウンロードしてから、個別にファイル ディスクに解凍します。

両方が必要ない場合は、プレーン ストリームをディスクに書き込んでバイナリ zip ファイルを取得することにより、どちらを実行するかを選択できます (ZipInputStream を使用する必要はありません)。または、ZipInputStream を使用して、各エントリからデータを読み取り、ディスクに書き込みます (ただし、ディスクへの書き込みにプレーンな入力ストリームを使用しないでください)。

于 2010-07-08T09:08:12.230 に答える
0

各エントリの内容を読んでから、 entry.closeEntry() を呼び出す必要があると思います

于 2010-07-08T08:48:55.110 に答える