Java 高效压缩zip
来源:互联网 发布:大学生有多少存款知乎 编辑:程序博客网 时间:2024/06/03 20:55
以前遇到文件压缩的功能是都直接从网上找一个,随便测试一下能用就行了。既不关心效率也没有好好的测一下是否支持内嵌文件夹的压缩。
现在仔细测试才发现网上好多都不支持内嵌文件夹的压缩。 支持的不是有问题就是速度比较慢。
框架里jar包里的类诸如IOUtils,FileUtils里没有提供压缩的方法。连commons-compress.jar里都没有现成的。
我决定自己写一个。真写的时候发现不是那么容易。目标是 给定一个文件夹路径和一个输出路径,将给定文件夹里的所有东西都压缩到zip里。
在commons-compress的文档里发现有一个支持多线程压缩的类 ParallelScatterZipCreator。我决定试一试。
在github里找到 ScatterSample.java 和 ScatterSampleTest.java 这两个类。这个demo不支持带文件夹的压缩。 文档里也没有给出带文件夹压缩的demo。没办法只能仔细阅
读这个demo从api里找线索了。
仔细摸索后,代码如下:
package test;import java.io.File;import java.io.IOException;import java.util.concurrent.ExecutionException;import org.apache.commons.compress.archivers.zip.ParallelScatterZipCreator;import org.apache.commons.compress.archivers.zip.ScatterZipOutputStream;import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;import org.apache.commons.compress.archivers.zip.ZipArchiveEntryRequest;import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;import org.apache.commons.compress.parallel.InputStreamSupplier;public class ScatterSample { private String rootPath; ParallelScatterZipCreator scatterZipCreator = new ParallelScatterZipCreator(); // ParallelScatterZipCreator api says: // 注意这个类不保证写入到输出文件的顺序。需要保持特定顺序的(manifests,文件夹)必须使用这个类的客户类进行处理 // 通常的做法是 在调用这个类的writeTo方法前把这些东西写入到ZipArchiveOutputStream ScatterZipOutputStream dirs = ScatterZipOutputStream .fileBased(File.createTempFile("whatever-preffix", ".whatever")); public ScatterSample(String rootPath) throws IOException { this.rootPath = rootPath; } public void addEntry(final ZipArchiveEntry zipArchiveEntry, final InputStreamSupplier streamSupplier) throws IOException { if (zipArchiveEntry.isDirectory() && !zipArchiveEntry.isUnixSymlink()) { dirs.addArchiveEntry(ZipArchiveEntryRequest.createZipArchiveEntryRequest(zipArchiveEntry, streamSupplier)); } else { scatterZipCreator.addArchiveEntry(zipArchiveEntry, streamSupplier); } } public void writeTo(final ZipArchiveOutputStream zipArchiveOutputStream) throws IOException, ExecutionException, InterruptedException { dirs.writeTo(zipArchiveOutputStream); dirs.close(); scatterZipCreator.writeTo(zipArchiveOutputStream); } public String getRootPath() { return rootPath; } public void setRootPath(String rootPath) { this.rootPath = rootPath; }}
package test;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.util.zip.ZipEntry;import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;import org.apache.commons.compress.parallel.InputStreamSupplier;import org.apache.commons.io.input.NullInputStream;import org.junit.Test;public class ScatterSampleTest { @Test public void testSample() throws Exception { long begin = System.currentTimeMillis(); final File result = new File("d:/test2/eclipse2.zip"); createZipFile("F:/Java/eclipseplusUIx64_best", result); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - begin) + " ms"); } class CustomInputStreamSupplier implements InputStreamSupplier { private File currentFile; public CustomInputStreamSupplier(File currentFile) { this.currentFile = currentFile; } @Override public InputStream get() { try { // InputStreamSupplier api says: // 返回值:输入流。永远不能为Null,但可以是一个空的流 return currentFile.isDirectory() ? new NullInputStream(0) : new FileInputStream(currentFile); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } } private void addEntry(String entryName, File currentFile, ScatterSample scatterSample) throws IOException { ZipArchiveEntry archiveEntry = new ZipArchiveEntry(entryName); archiveEntry.setMethod(ZipEntry.DEFLATED); final InputStreamSupplier supp = new CustomInputStreamSupplier(currentFile); scatterSample.addEntry(archiveEntry, supp); } private void compressCurrentDirectory(File dir, ScatterSample scatterSample) throws IOException { if (dir == null) { throw new IOException("源路径不能为空!"); } String relativePath = ""; if (dir.isFile()) { relativePath = dir.getName(); addEntry(relativePath, dir, scatterSample); return; } // 空文件夹 if (dir.listFiles().length == 0) { relativePath = dir.getAbsolutePath().replace(scatterSample.getRootPath(), ""); addEntry(relativePath + File.separator, dir, scatterSample); return; } for (File f : dir.listFiles()) { if (f.isDirectory()) { compressCurrentDirectory(f, scatterSample); } else { relativePath = f.getParent().replace(scatterSample.getRootPath(), ""); addEntry(relativePath + File.separator + f.getName(), f, scatterSample); } } } private void createZipFile(final String rootPath, final File result) throws Exception { File dstFolder = new File(result.getParent()); if (!dstFolder.isDirectory()) { dstFolder.mkdirs(); } File rootDir = new File(rootPath); final ScatterSample scatterSample = new ScatterSample(rootDir.getAbsolutePath()); compressCurrentDirectory(rootDir, scatterSample); final ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(result); scatterSample.writeTo(zipArchiveOutputStream); zipArchiveOutputStream.close(); }}
以解压后的eclipse文件为例,用时:4624 ms。比较了一下网上其他的方法,快了2倍多。这结果还算满意。 代码水平有限,只能到这儿了。如果有更精简的代码,欢迎指教。
0 0
- Java 高效压缩zip
- java 解压缩zip 压缩zip
- 7zip 文件高效压缩 解压
- Java Zip压缩
- java 压缩zip
- JAVA zip 压缩
- Java压缩zip文件
- java zip压缩
- JAVA zip压缩
- JAVA压缩/解压ZIP
- java zip压缩
- Java压缩/解压ZIP
- java zip压缩解压
- java zip压缩。解压缩
- java zip压缩
- java Zip 压缩文档
- java实现zip压缩
- java 实现zip压缩
- 关于时间复杂度
- DIP关键算法-去噪算法评价标准
- LeetCode[290] Word Pattern
- 51nod 1402 最大值(贪心)
- 【27.77%】【BZOJ 4066】简单题
- Java 高效压缩zip
- Ubuntu 下安装xgboost
- android View的三个构造方法 简单总结
- SpringMVC使用(1) 拦截器
- Struts2.5.2简单的使用注解
- [Leetcode] Jump Game II
- ubuntu开机自动启动
- Struts2.0学习笔记---plainText
- codeforces 717E - Paint it really, really dark gray