压缩(zipped)文件夹是无效的Java

时间:2011-12-19 12:09:18

标签: java

我正在尝试使用ZipOutputStream将文件从服务器压缩到文件夹中。 存档下载后,双击后无法打开。错误“压缩(压缩)文件夹无效”发生。但是,如果我从上下文菜单中打开它 - > 7zip - >打开文件它正常工作。这个问题可能是什么原因?

sourceFileName="./file.txt"'
                    sourceFile = new File(sourceFileName);

                    try {
                        // set the content type and the filename
                       responce.setContentType("application/zip");
                        response.addHeader("Content-Disposition", "attachment; filename=" + sourceFileName + ".zip");
                        responce.setContentLength((int) sourceFile.length());


                        // get a ZipOutputStream, so we can zip our files together
                        ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream());

                        // Add ZIP entry to output stream.
                        outZip.putNextEntry(new ZipEntry(sourceFile.getName()));

                        int length = 0;
                        byte[] bbuf = new byte[(int) sourceFile.length()];

                        DataInputStream in = new DataInputStream(new FileInputStream(sourceFile));
                        while ((in != null) && ((length = in.read(bbuf)) != -1)) {
                            outZip.write(bbuf, 0, length);
                        }

                        outZip.closeEntry();
                        in.close();
                        outZip.flush();
                        outZip.close();

2 个答案:

答案 0 :(得分:4)

7Zip可以打开各种各样的拉链格式,并且相对容忍奇怪。 Windows双击需要相对特定的格式,并且容忍度要低得多。

您需要查找zip format,然后使用十六进制编辑器(例如Hex Editor Neo)查看您的文件(和“好”文件),看看可能出现的问题。

(一种可能性是您使用了错误的压缩算法。还有其他几种变体需要考虑,尤其是您是否生成“目录”。)

答案 1 :(得分:3)

可能缺少close。可能是Windows无法处理zip中的路径编码。可能是Windows对目录结构有困难,或者路径名包含(反向)斜杠。所以这是侦探工作,尝试不同的文件。如果您立即将zip流式传输到HTTP响应,则必须将finish称为i.o. close


发布代码后:

问题是setContentLength给出原始文件大小。但是当给出时,它应该给出压缩的大小。

不需要

DataInputStream,此处应该readFully

    responce.setContentType("application/zip");
    response.addHeader("Content-Disposition", "attachment; filename=file.zip");

     //Path sourcePath = sourceFile.toPath();
     Path sourcePath = Paths.get(sourceFileName);

     ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream(),
            StandardCharsets.UTF-8);

     outZip.putNextEntry(new ZipEntry(sourcePath.getFileName().toString()));
     Files.copy(sourcePath, outZip);
     outZip.closeEntry();

最后的finishclose拉链。

     outZip.finish();
     //outZip.close();

     in.close();

我不确定(关于最佳代码风格)是否已经close the response output stream。 但是,如果不必关闭finish(),则flush()将不够,因为最后数据会写入zip。

对于具有例如西里尔字母的文件名,最好添加像UTF-8这样的Unicode字符集。事实上,让UTF-8成为世界范围内的世界语标准。

最后一点:如果只有一个文件可以GZipOutputstream使用file.txt.gz或查询浏览器的功能(请求参数)并将其压缩为file.txt