単一の InputStream から、ZIP 内の複数の XML ファイルを読み取るメソッドを作成したいと考えています。
このメソッドは ZipInputStream を開き、各 xml ファイルで対応する InputStream を取得し、それを XML パーサーに渡します。メソッドのスケルトンは次のとおりです。
private void readZip(InputStream is) throws IOException {
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
if (entry.getName().endsWith(".xml")) {
// READ THE STREAM
}
entry = zis.getNextEntry();
}
}
問題の部分は「// READ THE STREAM」です。ByteArrayInputStream を作成し、それをパーサーにフィードするという実用的なソリューションがあります。しかし、それはバッファを使用し、大きなファイルの場合、OutOfMemoryError が発生します。誰かがまだ興味がある場合のコードは次のとおりです。
int count;
byte buffer[] = new byte[2048];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((count = zis.read(buffer)) != -1) { out.write(buffer, 0, count); }
InputStream is = new ByteArrayInputStream(out.toByteArray());
理想的な解決策は、パーサーに元の ZipInputStream を供給することです。エントリの内容を Scanner で印刷するだけで機能するため、機能するはずです。
Scanner sc = new Scanner(zis);
while (sc.hasNextLine())
{
System.out.println(sc.nextLine());
}
しかし...私が現在使用しているパーサー(jdom2ですが、javax.xml.parsers.DocumentBuilderFactoryでも試しました)は、データの解析後にストリームを閉じます:/ . そのため、次のエントリを取得して続行することができません。
最後に質問は次のとおりです。
- ストリームを閉じない DOM パーサーを知っている人はいますか?
- ZipEntry から InputStream を取得する別の方法はありますか?
ありがとう。