ZipEntry.getInputStream()返回生成InputStream的异常

时间:2019-07-01 23:45:08

标签: java zipfile

我正在尝试使用java.util.zip.ZipFile从zip文件中读取一些xml文件,我希望获得一个输入流,然后可以使用sax解析器对其进行解析,但是由于错误的序言而不断出现Sax Exceptions。这意味着我没有从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 :(得分:0)

  

我的猜测是getInputStream()将流返回到不可读的压缩xml文件。

如果您正在读取已由ZIP压缩的条目,则不应发生这种情况。 ZipFile类将负责解压缩。

如果在将条目添加到ZIP文件之前压缩是由其他方式完成的,则ZipFile不会知道它已被压缩。您将需要:

  1. 弄清楚使用了哪种压缩方案。
  2. 在尝试解析流之前,先解压缩流。例如,用getInputStream()或类似的字符包装DeflaterInputStream的结果。

第三种可能性是流不是格式正确的XML…或根本不是XML。


建议:使用ZIP工具将有问题的ZIP条目提取到文件系统中的本地文件中,然后使用UNIX / Linux file命令之类的实用程序来确定实际的文件类型。 (不信任文件后缀。这可能会误导您。)