创建一个由两个文件组成的压缩文件时出错。

huangapple go评论76阅读模式
英文:

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

问题

I am trying to combine 2 files in one zip file

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("&quot;,&quot;");
            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("&quot;.&quot;))+"&quot;.zip&quot;";
        }
        InputStream pathStream = DownLoadHelper.getStreamAllFiles(l.toArray(new java.io.File[0]), downloadName);

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

    } else if (file.getAction().equals("&quot;open&quot;")) {
        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("&quot;application/octet-stream&quot;");
    response.setHeader("&quot;Content-Disposition&quot;",
            "&quot;attachment;filename=&quot; + fileName);


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

}

I have this error when trying to open the zip file

创建一个由两个文件组成的压缩文件时出错。

英文:

I am trying to combine 2 files in one zip file

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(&quot;{DISTRIB}&quot;, distrib));
String downloadName = file.getDownloadFileName() != null ? file.getDownloadFileName() : file.getPath();
if (file.getAction() == null || file.getAction().trim().isEmpty() || file.getAction().equals(&quot;download&quot;)) {
List&lt;java.io.File&gt; l = new ArrayList&lt;&gt;();
java.io.File f = new java.io.File(realPath);
l.add(f);
if(file.getDependOnCodeFiles() != null){
String[] paths  = file.getDependOnCodeFiles().split(&quot;,&quot;);
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(&quot;.&quot;))+&quot;.zip&quot;;
}
InputStream pathStream = DownLoadHelper.getStreamAllFiles(l.toArray(new java.io.File[0]), downloadName);
if (pathStream != null) {
if(downloadName.indexOf(&#39;/&#39;)!=-1) {
downloadName = downloadName.substring(downloadName.lastIndexOf(&#39;/&#39;)+1);
}
DownLoadHelper.downLoadFile(response, pathStream, downloadName);
} else {
logger.error(&quot;Le fichier &quot; + realPath + &quot; est introuvable!&quot;);
throw new TechnicalException(CodeError.CODE_ERTEMO0001, null);
}
} else if (file.getAction().equals(&quot;open&quot;)) {
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 &gt; 1) {
try( ByteArrayOutputStream baos = new ByteArrayOutputStream();ZipOutputStream zos = new ZipOutputStream(baos)){
for (int i = 0; i &lt; 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(&quot;application/octet-stream&quot;);
response.setHeader(&quot;Content-Disposition&quot;,
&quot;attachment;filename=&quot; + fileName);
ServletOutputStream out = response.getOutputStream();
IOUtils.copyLarge(pathStream, out);
out.flush();
FacesContext.getCurrentInstance().responseComplete();
IOUtils.closeQuietly(pathStream);
IOUtils.closeQuietly(out);
}

I have this error when trying to open the zip file

创建一个由两个文件组成的压缩文件时出错。

答案1

得分: 1

I presume you're trying to make a zip file with multiple files. The issues are in your getStreamAllFiles method as you don't close the zip entry after putting the content of the file, and you don't close the ZipOutputStream and the end of the loop, so the file loop should look like:

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());

i.e. move the zos.closeEntry() inside the loop through the files.

Without moving it inside the listDoc.length loop, if you have more than one file you will not be closing the ZipEntry properly at the end of each entry. You also need to issue a close() on the ZipOutputStream, as otherwise it will not write the end-of-zip directory (which is shown as an error End-of-central-directory signature not found if you test the file under a command line tool).

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.

英文:

I presume you're trying to make a zip file with multiple files. The issues are in your getStreamAllFiles method as you don't close the zip entry after putting the content of the file, and you don't close the ZipOutputStream and the end of the loop, so the file loop should look like:

for (int i = 0; i &lt; 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());

i.e. move the zos.closeEntry() inside the loop through the files.

Without moving it inside the listDoc.length loop, if you have more than one file you will not be closing the ZipEntry properly at the end of each entry. You also need to issue a close() on the ZipOutputStream, as otherwise it will not write the end-of-zip directory (which is shown as an error End-of-central-directory signature not found if you test the file under a command line tool.

> 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.

huangapple
  • 本文由 发表于 2020年8月11日 04:03:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/63347248.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定