【问题标题】:How to create ZIP file for a list of "virtual files" and output to httpservletresponse如何为“虚拟文件”列表创建 ZIP 文件并输出到 httpservletresponse
【发布时间】:2011-06-08 19:12:15
【问题描述】:

我的目标是将多个 java.io.File 对象放入一个 zip 文件并打印到 HttpServletResponse 供用户下载。

这些文件是由 JAXB 编组器创建的。它是一个 java.io.File 对象,但它实际上不在文件系统上(它只在内存中),所以我无法创建 FileInputStream。

我见过的所有资源都使用 OutputStream 来打印 zip 文件内容。但是,所有这些资源都使用 FileInputStream(我不能使用)。

有谁知道我怎么能做到这一点?

【问题讨论】:

  • java.io.File 是什么意思? File 对象只是一个花哨的地址对象;它不携带任何文件内容。您的数据在哪里?

标签: java spring servlets spring-mvc zip


【解决方案1】:

看看Apache Commons Compress 库,它提供了您需要的功能。

当然,“埃里克森”对您的问题的评论是正确的。您将需要文件内容而不是 java.io.File 对象。在我的示例中,我假设您有一个方法 byte[] getTheContentFormSomewhere(int fileNummer) 返回第 fileNummer 文件的文件内容(在内存中)。 -- 当然这个功能设计的很差,但只是为了说明。

它应该有点像这样:

void compress(final OutputStream out) {
  ZipOutputStream zipOutputStream = new ZipOutputStream(out);
  zipOutputStream.setLevel(ZipOutputStream.STORED);

  for(int i = 0; i < 10; i++) {
     //of course you need the file content of the i-th file
     byte[] oneFileContent = getTheContentFormSomewhere(i);
     addOneFileToZipArchive(zipOutputStream, "file"+i+"."txt", oneFileContent);
  }

  zipOutputStream.close();
}

void addOneFileToZipArchive(final ZipOutputStream zipStream,
          String fileName,
          byte[] content) {
    ZipArchiveEntry zipEntry = new ZipArchiveEntry(fileName);
    zipStream.putNextEntry(zipEntry);
    zipStream.write(pdfBytes);
    zipStream.closeEntry();
}

你的 http 控制器的片段:

HttpServletResponse response
...
  response.setContentType("application/zip");
  response.addHeader("Content-Disposition", "attachment; filename=\"compress.zip\"");
  response.addHeader("Content-Transfer-Encoding", "binary");
  ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
  compress(outputBuffer);
  response.getOutputStream().write(outputBuffer.toByteArray());
  response.getOutputStream().flush();
  outputBuffer.close();

【讨论】:

    【解决方案2】:

    原来我是个白痴 :) 正在“创建”的文件正在保存到无效路径并吞下异常,所以我认为它正在“创建”正常。但是,当我尝试实例化一个新的 FileInputStream 时,它抱怨该文件不存在(这是正确的)。我脑洞大开,并假设 java.io.File 对象实际上在某处包含文件信息。但正如埃里克森指出的那样,这是错误的。

    感谢 Ralph 提供的代码,我在解决无效路径问题后使用它。

    我的代码:

    ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
    byte[] buf = new byte[1024];
    
    File file;
    InputStream in;
    // Loop through entities
    for (TitleProductAccountApproval tpAccountApproval : tpAccountApprovals) {
        // Generate the file    
        file = xmlManager.getXML(
            tpAccountApproval.getTitleProduct().getTitleProductId(), 
            tpAccountApproval.getAccount().getAccountId(), 
            username);
    
        // Write to zip file
        in = new FileInputStream(file);
        out.putNextEntry(new ZipEntry(file.getName()));
    
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
    
        out.closeEntry();
        in.close();
    }
    
    out.close();
    

    【讨论】:

    • 无效的路径问题? - 你是什么意思 - 我的答案代码中是否存在 serios 错误?
    猜你喜欢
    • 2015-02-27
    • 2011-01-06
    • 2018-08-10
    • 2013-08-27
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多