ZipEntry.getInputStream () возвращает исключение, генерирующее InputStream - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь прочитать некоторые xml-файлы из zip-файла, используя java.util.zip.ZipFile, я надеялся получить поток ввода, который затем мог бы анализировать с помощью синтаксического анализатора саксофона, но продолжал получать исключения Sax из-за неисправных прологов.Это означает, что я не получаю то, что ожидаю от inputStream.

Чего мне не хватает?

if (path.endsWith(".zip")){
            ZipFile file = new ZipFile(path);
            Enumeration<? extends ZipEntry> entries = file.entries();
            while (entries.hasMoreElements()){
                methodThatHandlesXmlInputStream(file.getInputStream(entries.nextElement()));
            }
        }

Обновление: Я пытался сделать минимальный проверяемыйпример, чтобы воспроизвести проблему, но она сработала, что говорит мне, что проблема должна быть связана с моим methodThatHandlesXmlInputStream неправильным обращением с inputStream.Спасибо всем за любезную помощь

Рабочий пример

import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.XMLReader;

public class Main {
    public static void main(String[] args){
        try{
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setNamespaceAware(true);
            SAXParser parser = factory.newSAXParser();
            XMLReader reader = parser.getXMLReader();
            reader.setContentHandler(new MyContentHandler());

            InputStream uncompressedFileStream = new FileInputStream("Sample.xml");
            InputSource inputSourceFromFile = new InputSource(uncompressedFileStream);

            InputStream inputStreamDB = inputFromDB();
            InputSource inputSourceFromDB = new InputSource(inputStreamDB);

            ZipFile zipFile = new ZipFile("Sample.zip");
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            InputStream inputStreamFromZip = null;
            if (entries.hasMoreElements())
                inputStreamFromZip = zipFile.getInputStream(entries.nextElement());
            InputSource inputSourceFromZip = new InputSource(inputStreamFromZip);

            reader.parse( inputSourceFromFile );
            reader.parse( inputSourceFromZip );
            reader.parse( inputSourceFromDB );
        }catch (Exception ex){
            System.out.println(ex);
        }
    }

    private static InputStream inputFromDB() throws SQLException {
        Connection localDb = DriverManager.getConnection("jdbc:mysql://localhost/test_database","java","javaPasswd");
        PreparedStatement statement = localDb.prepareStatement("SELECT blob_column FROM test_table WHERE id=1");
        ResultSet rs = statement.executeQuery();
        rs.next();
        return rs.getBinaryStream(1); 
    }

    private static class MyContentHandler extends DefaultHandler{
        @Override
        public void endDocument() throws SAXException {
            System.out.println("Document ended successfully");
        }
        @Override
        public void startDocument() throws SAXException {
            System.out.println("Document starts successfully");
        }
    }
}

Решение: Прошу прощения, после того, как файл был правильно проанализирован один раз,Мой метод попытался проанализировать его снова, оборачивая его как FileInputStream, который генерировал нечитаемый InputStream.Спасибо всем!

1 Ответ

0 голосов
/ 02 июля 2019

Я предполагаю, что getInputStream () возвращает поток в сжатый XML-файл, который будет нечитаемым.

Если вы читаете запись, сжатую ZIP, это не должно произойти. Классы ZipFile позаботятся о распаковке.

Если сжатие было сделано чем-то другим до добавления записи в ZIP-файл, то ZipFile не будет знать, что оно сжато. Вам нужно будет:

  1. Выясните, какая схема сжатия использовалась.
  2. Распакуйте поток самостоятельно, прежде чем пытаться его проанализировать. Например, оберните результат getInputStream() значением DeflaterInputStream или аналогичным.

Третья возможность состоит в том, что поток не является правильно сформированным XML ... или вообще не XML.


Предложение: Используйте инструмент ZIP, чтобы извлечь поврежденную запись ZIP в локальный файл в файловой системе, а затем используйте утилиту, такую ​​как команда UNIX / Linux file, чтобы выяснить, каков реальный тип файла. (Не доверяйте суффиксу файла. Это может ввести вас в заблуждение.)

...