Попробуйте блок, вызывающий поток, закрытый IOException

Мой вопрос касается этого исключения

java.io.IOException: Stream closed
java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67)
java.util.zip.InflaterInputStream.read(InflaterInputStream.java:142)
java.io.FilterInputStream.read(FilterInputStream.java:107)
com.avnet.css.servlet.PartNotificationFileServlet.doGet(PartNotificationFileServlet.java:51)
javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

Поэтому мы недавно обновили наш код для Java 7, и нам пришлось реализовать блок try для объявления ZipFile. Похоже, это приводит к закрытию входного потока, чего не было раньше, когда не было блока try. Не уверен, что понимаю, почему, когда он объявлен перед блоком. Кто-нибудь может объяснить или предложить решение?

    String uri = req.getRequestURI();
    String[] tokens = uri.split("/");
    String folder = tokens[tokens.length - 2];//req.getParameter("folder");
    String filename = tokens[tokens.length - 1];req.getParameter("filename");
    Properties properties = new CSSProperties();
    InputStream inputStream = null;
    if(!folder.contains("_AVT")){
        //below is the new try block, when the declaration inside the parenthesis is on its own, instead of inside try, it works fine.  
        try (ZipFile docsZip = new ZipFile(new File(properties.getProperty(PCN_DIR) + File.separator + folder + File.separator + "Documents.zip"))) {
            ZipEntry entry = docsZip.getEntry(filename);
            if (entry != null)                              
                inputStream = docsZip.getInputStream(entry);
        }
    }
    else{
        String decodedFileName = URLDecoder.decode(filename, "UTF-8");
        File file = new File(properties.getProperty(PCN_DIR) + File.separator + folder + File.separator + decodedFileName);
        if(file.exists())
            inputStream = new FileInputStream(file);
    }
    if(inputStream != null){
        resp.setHeader("Content-Type", MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(filename));
        ServletOutputStream out = resp.getOutputStream();
        byte[] buffer = new byte[2048];
        int read;
        while ((read = inputStream.read(buffer)) > 0) //this is line 51, where the error occurs
            out.write(buffer, 0, read);
        inputStream.close();
        out.close();
    }

2 ответа

Решение

В текущем коде вы используете оператор try-with-resources, поэтому ваш ZipFile docsZip закрывается, как только try выполнен.

Когда вы ставите декларацию docsZip в пределах try он не будет закрыт (обратите внимание, что это должно быть сделано где-то после out.close(),

Это документированное поведение в ZipFile#close:

Закрытие этого ZIP-файла закроет все входные потоки, ранее возвращенные вызовами метода getInputStream.

(Вызов инструкции Java 7 try-with-resources close автоматически в конце блока.)

Другие вопросы по тегам