是否有更好的方法来压缩java中的大文件?
问题描述:
我有大约5到6个大文件,每个大小3 GB。我的目标是压缩这些文件,然后使用文件servlet传输它。我的当前代码需要大量的时间,导致浏览器上的超时会话。有没有更好的方法来压缩文件。是否有更好的方法来压缩java中的大文件?
File zipFile=new File(downloadedFileLocation.getAbsolutePath()+"/Download.zip");
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
for(File f:downloadedFileLocation.listFiles()) {
byte[] buffer = new byte[1024];
ZipEntry ze= new ZipEntry(f.getName());
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(f.getAbsolutePath());
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
f.delete();
}
zos.close();
fos.close();
更改缓冲区大小会有什么区别吗?
任何人都可以建议任何更好的方式,可以更快地完成压缩。
答
任何人都可以提出任何更好的办法,其中拉链可以做得更快
不,你不能这样做拉拉链更快,但你可以做到这一点“活”。
在传输之前,不要将压缩内容写入临时文件。直接写入Servlet中的OutputStream
。
结果是压缩的内容会在压缩时传输,因此连接不会超时,并且总响应时间会缩短。
您还应该使用try-with-resources进行资源管理,并使用更新的NIO文件类以方便使用和更好的错误消息。
事情是这样的:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/zip");
try (ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream())) {
for (File f : downloadedFileLocation.listFiles()) {
zos.putNextEntry(new ZipEntry(f.getName()));
Files.copy(f.toPath(), zos);
Files.delete(f.toPath());
}
}
}
我在那里留下的delete()
,但是这取决于你在做什么,做这件事的时候这种方式可能不恰当的。或者至少在下载完成之前不要删除,即在for
循环结束之前。
物理说“不”。如果无法并行操作,则文件的大小和数量将呈线性关系。 – duffymo
像@duffymo说的。这就是为什么一些网站显示“你的下载将很快准备就绪”,然后生成并向你发送链接或使用一些漂亮的客户端更新来使URL可用。 –
您的缓冲区非常小(现代尺寸为131072或更多),但不太可能产生足够大的差异。你可能会使用'zos.setMethod(ZipOutputStream.STORED);'来避免压缩,但你真的不应该期望能够同步处理15GB的数据。在后台进行压缩,存储结果,并让客户进行投票直至完成。 –