当我尝试从 2 个文件创建 zip 时出错

Error when i am trying to create a zip from 2 files

我正在尝试将 2 个文件合并到一个 zip 文件中

myMainMethod

private void downloadFileByTypeInner(StaticDocument file, String productCode, int productVersion) throws IOException, TechnicalException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletResponse response = (HttpServletResponse) ec.getResponse();
    String distrib = MultinetFrontHelper.getDefaultDitrib();
    String realPath = findRealPath(ec, file.getPath().replace("{DISTRIB}", distrib));
    String downloadName = file.getDownloadFileName() != null ? file.getDownloadFileName() : file.getPath();

    if (file.getAction() == null || file.getAction().trim().isEmpty() || file.getAction().equals("download")) {
        List<java.io.File> l = new ArrayList<>();
        java.io.File f = new java.io.File(realPath);
        l.add(f);
        if(file.getDependOnCodeFiles() != null){
            String[] paths  = file.getDependOnCodeFiles().split(",");
            for (String codefile : paths) {

                StaticDocument file2 = libraryBusinessService.getFileByCodeType(codefile, productCode, productVersion);
                if((file2 != null)) {
                    l.add(new java.io.File(findRealPath(ec, file2.getPath())));
                }
            }
            downloadName = downloadName.substring(0,downloadName.lastIndexOf("."))+".zip";
        }
        InputStream pathStream = DownLoadHelper.getStreamAllFiles(l.toArray(new java.io.File[0]), downloadName);

        if (pathStream != null) {
            if(downloadName.indexOf('/')!=-1) {
                downloadName = downloadName.substring(downloadName.lastIndexOf('/')+1);
            }
            DownLoadHelper.downLoadFile(response, pathStream, downloadName);
        } else {
            logger.error("Le fichier " + realPath + " est introuvable!");
            throw new TechnicalException(CodeError.CODE_ERTEMO0001, null);
        }

    } else if (file.getAction().equals("open")) {
        final FacesContext ctx = FacesContext.getCurrentInstance();
        final ExternalContext extContext = ctx.getExternalContext();
        try {
            extContext.redirect(file.getPath());
        } catch (final IOException ioe) {
            throw new FacesException(ioe);

        }
    }
}

getStreamAllFiles

public static InputStream getStreamAllFiles(final File[] listDoc, String nameZIP) throws IOException {
    InputStream stream = null;
    if (listDoc != null) {
        if (listDoc.length == 1) {
            stream = new  ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[0]));
        } else if (listDoc.length > 1) {
            try( ByteArrayOutputStream baos = new ByteArrayOutputStream();ZipOutputStream zos = new ZipOutputStream(baos)){

                for (int i = 0; i < listDoc.length; i++) {

                    try(InputStream fis = new  ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[i]));BufferedInputStream bis = new BufferedInputStream(fis)){
                        zos.putNextEntry(new ZipEntry(listDoc[i].getName()));
                        byte[] bytes = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = bis.read(bytes)) != -1) {
                            zos.write(bytes, 0, bytesRead);
                        }
                    }
                }

                zos.closeEntry();

                stream = new ByteArrayInputStream(baos.toByteArray());
            }
        }
    }
    return stream;
}

downLoadFile

public static void downLoadFile(HttpServletResponse response,InputStream pathStream,String fileName) throws IOException {
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition",
            "attachment;filename=" + fileName);


    ServletOutputStream out = response.getOutputStream();
    IOUtils.copyLarge(pathStream, out);
    out.flush();
    FacesContext.getCurrentInstance().responseComplete();
    IOUtils.closeQuietly(pathStream);
    IOUtils.closeQuietly(out);

}

我在尝试打开 zip 文件时遇到此错误

我假设您正在尝试制作一个包含多个文件的 zip 文件。问题出在您的 getStreamAllFiles 方法中,因为您在放置文件内容后没有关闭 zip 条目,并且您没有关闭 ZipOutputStream 和循环结束,所以文件循环应如下所示:

for (int i = 0; i < listDoc.length; i++) {

    try(InputStream fis = new  ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[i]));BufferedInputStream bis = new BufferedInputStream(fis)){
        zos.putNextEntry(new ZipEntry(listDoc[i].getName()));
        byte[] bytes = new byte[1024];
        int bytesRead;
        while ((bytesRead = bis.read(bytes)) != -1) {
            zos.write(bytes, 0, bytesRead);
        }
        zos.closeEntry();
    }
}
zos.close();
stream = new ByteArrayInputStream(baos.toByteArray());

即在文件循环中移动 zos.closeEntry()

如果不将其移动到 listDoc.length 循环内,如果您有多个文件,您将无法在每个条目末尾正确关闭 ZipEntry。您还需要在 ZipOutputStream 上发出 close(),否则它不会写入 end-of-zip 目录(如果您在命令行工具下测试该文件,则显示为错误 End-of-central-directory signature not found .

In addition, I'd move the allocation of the byte buffer outside the file loop as you only need to allocate it once, and reuse the same buffer for all the files you're writing.