废话少说,直接上代码和结果图.
main函数执行方法 如下 :
public static void compareZipSpeed() {
String srcDir = "D:\\Documents\\Desktop\\testZipSpeed\\testDir";
ZipFileUtil z3 = new ZipFileUtil();
try {
z3.test(srcDir, "D:\\Documents\\Desktop\\testZipSpeed\\zip_file.zip");
} catch (IOException e) {
e.printStackTrace();
}
ZipNioUtil z4 = new ZipNioUtil();
try {
z4.test(srcDir, "D:\\Documents\\Desktop\\testZipSpeed\\zip_nio.zip", true);
} catch (Exception e) {
e.printStackTrace();
}
ZipStreamUtil z1 = new ZipStreamUtil();
try {
z1.test(srcDir, "D:\\Documents\\Desktop\\testZipSpeed\\zip_stream.zip");
} catch (IOException e) {
e.printStackTrace();
}
}
下面是3个 压缩文件夹的 Util 工具类 :
1. zipFile 压缩方式
class ZipFileUtil {
public void test(String srcDir, String destFile) throws IOException {
long start = System.currentTimeMillis();
File rootFile = autoCreateDir(new File(srcDir),false);
var zipPath = destFile;
var zip = new ZipFile(zipPath);
zip.setCharset(Charset.forName("UTF-8"));
try {
zip.addFolder(rootFile);
zip.close();
} catch (ZipException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println(this.getClass().getName() + " -> finish . cost:" + (end - start) + "ms");
}
}
2. zipNio 压缩方式
class ZipNioUtil {
public void test(String srcDir, String destFile, boolean ifAllowReWrite) throws IOException {
if (new File(destFile).exists()) {
if (ifAllowReWrite) {
new File(destFile).delete();
} else {
throw new RuntimeException("此压缩目标文件路径--文件已存在!");
}
}
autoCreateDir( new File(destFile),false );
long start = System.currentTimeMillis();
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(destFile)));
WritableByteChannel writableByteChannel = Channels.newChannel(zos);
addFolderToZip(srcDir, srcDir, zos, writableByteChannel);
zos.close();
long end = System.currentTimeMillis();
System.out.println(this.getClass().getName() + " -> finish . cost:" + (end - start) + "ms");
}
private static void addFolderToZip(String folderPath, String srcDir, ZipOutputStream zos, WritableByteChannel writableByteChannel) throws IOException {
File folder = new File(folderPath);
if (folder != null && folder.exists() && folder.isDirectory()) {
File[] files = folder.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
if (file != null && file.exists()) {
if (file.isDirectory()) {
addFolderToZip(file.getAbsolutePath(), srcDir, zos, writableByteChannel);
} else {
String fileName = file.getAbsolutePath().substring(srcDir.length() + 1);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
FileInputStream fis = new FileInputStream(file);
FileChannel fileChannel = fis.getChannel();
fileChannel.transferTo(0, file.length() - 1, writableByteChannel);
}
}
}
}
}
}
}
3. ZipOutputStream 压缩方式
class ZipStreamUtil {
public void test(String srcDir, String destFile) throws IOException {
long start = System.currentTimeMillis();
String sourceFolder = srcDir;
String zipFile = destFile;
autoCreateDir(new File(zipFile),false);
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
BufferedOutputStream bos = new BufferedOutputStream(zos);
addFolderToZip(sourceFolder, sourceFolder, zos, bos);
bos.close();
zos.close();
fos.close();
long end = System.currentTimeMillis();
System.out.println(this.getClass().getName() + " -> finish . cost:" + (end - start) + "ms");
}
private static void addFolderToZip(String folderPath, String sourceFolder, ZipOutputStream zos, BufferedOutputStream bos) throws IOException {
File folder = new File(folderPath);
File[] files = folder.listFiles();
if (files != null && files.length > 0) for (File file : files) {
if (file.isDirectory()) {
addFolderToZip(file.getAbsolutePath(), sourceFolder, zos, bos);
} else {
String filePath = file.getAbsolutePath().substring(sourceFolder.length() + 1);
ZipEntry zipEntry = new ZipEntry(filePath);
zos.putNextEntry(zipEntry);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[102400];
int length;
while ((length = bis.read(buffer)) > 0) {
bos.write(buffer, 0, length);
}
bos.flush();
bis.close();
fis.close();
}
}
}
}
三种压缩方式 速度对比:
总结,经过对比,由于 ZipNio 使用了 FileChannel ,速度更快一些。想了解底层原理的同学也可以去研究下其中的源码