Java-ZipUtil
Posted jhxxb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java-ZipUtil相关的知识,希望对你有一定的参考价值。
Zip 压缩工具类,不支持压缩空文件夹。
简单版
import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipUtil public static void main(String[] args) zipCompression("D:\\\\123.zip", "D:\\\\123", "D:\\\\456", "D:\\\\er4.zip"); static void zipCompression(String zipPath, String... paths) Path[] ps = new Path[paths.length]; for (int i = 0; i < paths.length; i++) ps[i] = Paths.get(paths[i]); zipCompression(Paths.get(zipPath), ps); static void zipCompression(Path zipPath, Path... paths) long beginTime = Instant.now().toEpochMilli(); try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath.toFile()))) for (Path path : paths) Files.walkFileTree(path, new SimpleFileVisitor<Path>() @Override // 访问一个文件 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException zos.putNextEntry(new ZipEntry(file.toString().replace(path.getParent().toString(), ""))); Files.copy(file, zos); zos.closeEntry(); return FileVisitResult.CONTINUE; ); catch (IOException e) e.printStackTrace(); System.out.println("耗时:" + (Instant.now().toEpochMilli() - beginTime));
内存映射+管道+异步线程版,效率似乎没有什改变。。。。。。
import java.io.*; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.Pipe; import java.nio.channels.WritableByteChannel; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.concurrent.CompletableFuture; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipUtil public static void main(String[] args) zipCompression("D:\\\\123.zip", "D:\\\\123", "D:\\\\456", "D:\\\\er4.zip"); static void zipCompression(String zipPath, String... paths) Path[] ps = new Path[paths.length]; for (int i = 0; i < paths.length; i++) ps[i] = Paths.get(paths[i]); zipCompression(Paths.get(zipPath), ps); static void zipCompression(Path zipPath, Path... paths) long beginTime = Instant.now().toEpochMilli(); try (FileOutputStream fileOutputStream = new FileOutputStream(zipPath.toFile()); WritableByteChannel out = Channels.newChannel(fileOutputStream)) Pipe pipe = Pipe.open(); // 异步任务往通道中塞入数据 CompletableFuture.runAsync(() -> runCompressionTask(pipe, paths)); // 读取通道中数据 Pipe.SourceChannel source = pipe.source(); ByteBuffer buffer = ByteBuffer.allocate(2048); // ByteBuffer buffer = ByteBuffer.allocateDirect(2048); while (source.read(buffer) >= 0) buffer.flip(); out.write(buffer); buffer.clear(); catch (IOException e) e.printStackTrace(); System.out.println("耗时:" + (Instant.now().toEpochMilli() - beginTime)); // 异步任务 public static void runCompressionTask(Pipe pipe, Path... paths) try (Pipe.SinkChannel sink = pipe.sink(); OutputStream os = Channels.newOutputStream(sink); ZipOutputStream zos = new ZipOutputStream(os); WritableByteChannel out = Channels.newChannel(zos)) for (Path path : paths) Files.walkFileTree(path, new SimpleFileVisitor<Path>() @Override // 访问一个目录 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException if (dir.toFile().list().length == 0) // 无法打包空文件夹 // zos.putNextEntry(new ZipEntry(dir.toString().replace(path.getParent().toString(), "") + File.separator)); // System.out.println(dir.toString().replace(path.getParent().toString(), "") + File.separator); // zos.closeEntry(); return FileVisitResult.CONTINUE; @Override // 访问一个文件 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException zos.putNextEntry(new ZipEntry(file.toString().replace(path.getParent().toString(), ""))); MappedByteBuffer mappedByteBuffer = new RandomAccessFile(file.toFile(), "r").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, attrs.size()); out.write(mappedByteBuffer); // FileChannel fileChannel = new FileInputStream(file.toFile()).getChannel(); // fileChannel.transferTo(0, fileChannel.size(), out); // fileChannel.close(); zos.closeEntry(); return FileVisitResult.CONTINUE; ); zos.finish(); catch (IOException e) e.printStackTrace();
用到了 NIO 相关特性
https://juejin.im/post/5d5626cdf265da03a65312be
https://www.cnblogs.com/jhxxb/p/11272727.html
https://www.cnblogs.com/jhxxb/p/11303947.html
以上是关于Java-ZipUtil的主要内容,如果未能解决你的问题,请参考以下文章