Я хотел бы написать метод, который считывает несколько файлов XML внутри ZIP из одного InputStream.
Этот метод откроет 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();
}
}
Проблемной частью является «// ПРОЧИТАЙТЕ ПОТОК». У меня есть рабочее решение, которое состоит в том, чтобы создать 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 sc = new Scanner(zis);
while (sc.hasNextLine())
{
System.out.println(sc.nextLine());
}
Но... Парсер, который я сейчас использую (jdom2, но я также пробовал с javax.xml.parsers.DocumentBuilderFactory), закрывает поток после разбора данных:/. Поэтому я не могу получить следующую запись и продолжить.
Итак, наконец, вопрос:
- Кто-нибудь знает парсер DOM, который не закрывает свой поток?
- Есть ли другой способ получить InputStream из ZipEntry?
Спасибо.