Zip Outputstream已关闭。 java.io.IOException:Stream已关闭

时间:2017-05-03 11:33:17

标签: java

如何解决此异常?我需要在zip上添加多个xlsx。第一个xlsx被添加到列表中,但第二个会抛出此错误:

public void downloadData() throws Exception {

    FacesContext fc = FacesContext.getCurrentInstance();
    setSourceList(new ArrayList<String>());
    setTargetList(new ArrayList<String>());

    List<String> tempList = dualList.getTarget();
    System.out.println(tempList.size());

    if (tempList != null && tempList.size() > 0) {

        ExternalContext ec = fc.getExternalContext();
        ec.responseReset();

        ec.setResponseContentType("application/zip");
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"Export.zip\"");
        ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outByteStream);
        OutputStream outStream = ec.getResponseOutputStream();

        for (int i = 0; i < tempList.size(); i++) {

            outByteStream = new ByteArrayOutputStream();
            //zip = new ZipOutputStream(outByteStream);
            // outStream = ec.getResponseOutputStream();

            int id = ownerNameIdMap.get(tempList.get(i));
            String oName = tempList.get(i);
            String fileName = oName + ".xlsx";

            if (petList != null && petList.size() > 0) {
                petList.clear();
            }

            workBook = new XSSFWorkbook();

            OwnerModel ownerModel = ownerMap.get(id);
            ownerFirstName = ownerModel.getFirstName();
            ownerLastName = ownerModel.getLastName();
            workSheet = workBook.createSheet(ownerLastName + ", " + ownerFirstName);
            petList = iOwnerRepository.getActivePetsOfOwner(ownerModel.getId());
            petCount = petList.size();
            createMasterSheet();
            renderSheet(ownerModel);

            workBook.write(outByteStream);
            //addEntry(zip, fileName, outByteStream);
            ZipEntry entry = new ZipEntry(fileName);
            zip.putNextEntry(entry);
            System.out.println(fileName);
            zip.write(outByteStream.toByteArray());
            zip.closeEntry();
            workBook.write(zip);
            outStream.write(outByteStream.toByteArray());


        }

        outStream.flush();
        outStream.close();
        zip.close();
        fc.responseComplete();

    }

}

我的堆栈跟踪

SEVERE: Received 'java.io.IOException' when invoking action listener '#{exportViewBean.downloadData}' for component 'j_idt83'
May 03, 2017 11:24:13 AM javax.faces.event.MethodExpressionActionListener processAction
SEVERE: java.io.IOException: Stream closed
    at java.util.zip.ZipOutputStream.ensureOpen(ZipOutputStream.java:97)
    at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:190)
    at com.fetchinglife.modules.dataimport.views.ExportViewBean.downloadData(ExportViewBean.java:218)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:153)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:771)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:105)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

2 个答案:

答案 0 :(得分:0)

尝试合并使用outByteStream。您在for循环之前打开它并使用它初始化zip但在for循环内您将另一个ByteArrayOutputStream实例分配给outByteStream,然后使用此实例。我不确定这是否会导致您的异常,但可能值得尝试......

答案 1 :(得分:0)

你好,我有这个问题,仅将第一个文件添加到zip流中并抛出流关闭异常,因此我首先将文件转换为字节数组,而不在zip.write()方法中使用流,将我的代码更改为跟随

private byte[] _toByteArray(InputStream in) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;

        while ((len = in.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }

        return os.toByteArray();
    }

public byte[] getAllAssignmentSubmissionResourceAsZip(
        long lmsAssignmentId) {

        List<DLFileEntry> dlFileEntries =
            lmsAssignmentFinder.getLastAssignmentSubmissionsResourceByLA(
                lmsAssignmentId);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        ZipOutputStream zout = new ZipOutputStream(baos);

        try {
            for (DLFileEntry dl : dlFileEntries) {
                byte[] dlBytes = _toByteArray(dl.getContentStream());//output of getContenStream is InputSream type

                ZipEntry zip = new ZipEntry(dl.getFileName());

                zout.putNextEntry(zip);

                zout.write(dlBytes);
                zout.closeEntry();
            }
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            zout.flush();
            zout.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return baos.toByteArray();
    }

并设置为响应:


byte[] zipFile =
            _lmsAssignmentService.getAllAssignmentSubmissionResourceAsZip(
                siteId, assignmentId);

        String fileName = "test";

        String dispositionDesc = String.format(
            "attachment;filename=\"%s\"", fileName);

        Response.ResponseBuilder responseBuilder = Response.ok(zipFile);

        responseBuilder.header("Content-Disposition", dispositionDesc);
        responseBuilder.header("Content-Type", "application/zip");

我希望这个答案有帮助