我正在尝试使用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();
答案 0 :(得分:4)
您需要查找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();
最后的finish
或close
拉链。
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
。