3

変換を適用したい多数のXMLファイルを含むZipInputStreamがあります。次のコードは、XSLTファイルとZIPファイルをロードし、ZIPエントリをループして、それぞれに変換を適用しようとします。ただし、変換を実行した後、変換関数が入力ストリームを閉じているように見えます。ストリームが閉じているため、getNextEntry()関数が失敗します。

この問題を回避する簡単な方法はありますか(入力ストリームを開いたままにして、ZipInputStreamを次のエントリに移動できるようにする)、またはここでもっと基本的なものが欠けていますか?

TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource(xsltFileName));

FileInputStream fis = new FileInputStream(fileName);
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry ze = null;

while ((ze = zis.getNextEntry()) != null)
{
    String newFileName = ze.getName();
    transformer.transform(new StreamSource(zis), new StreamResult(new FileOutputStream(newFileName)));
}

私は解決策を探そうとしましたが、意味のあることは何も思いつかないようです。アイデアやフィードバックをいただければ幸いです。

4

5 に答える 5

5

考えられる解決策の1つは、ZipInputStreamを拡張し(これは最終的なものではありません)、何もしないようにcloseメソッドをオーバーライドすることです。もちろん、それを自分で閉じることを確認する必要があります。これは、super.close()を呼び出すだけの2番目のカスタムcloseメソッドを使用して行うことができます。

class MyZIS extends ZipInputStream {

    public MyZIS(InputStream in) {
        super(in);
    }

    @Override
    public void close() throws IOException {
    }

    public void myClose() throws IOException {
        super.close();
    }
}
于 2012-10-19T16:10:42.737 に答える
1

一般的に受け入れられているプロトコルは、「入力ストリームを作成する人は使用後にそれを閉じる必要がある」というものであり、XSLTプロセッサ(Xalan?)はこの規則に従っていないようです。その場合、回避策(別のXSLTプロセッサーへの移動は別として!)は、ZipInputStreamをラップし、インターセプトするclose()呼び出しを除いて、基になるZipInputStreamへのすべての呼び出しを渡すフィルターストリームを作成することです。

于 2012-10-19T13:57:13.793 に答える
0

実際には、zipアーカイブを読み取るためにクラスZipFileを使用する必要があります。次に、次のようにzipエントリの入力ストリームを取得します。

zipfile.getInputStream(zipEntry);
于 2012-10-19T14:45:51.167 に答える
-1

おそらく、あなたがする必要があるのは、zip入力を一時バッファに読み込み、それをトランスフォーマーへのソースとして使用することです。私の理解では、トランスフォーマーは変換がどうあるべきかを決定するためにストリーム全体を読み取る必要があるため、入力ストリームを閉じなかったとしても、次の読み取りはEOFにヒットします。

おそらくこのようなものですか?(最適化は行われていません)

    byte[] bytes = new byte[(int) entry.getSize()];
    zis.read(bytes);
    ByteArrayInputStream out = new ByteArrayInputStream(bytes);
    transformer.transform(new StreamSource(zis), new StreamResult(new FileOutputStream(newFileName)));    }
于 2012-10-19T16:51:41.327 に答える
-1

設定できるプロパティがあります:IsStreamOwner、これがfalseの場合、基になるストリームは閉じられません。

于 2014-09-16T12:13:55.203 に答える