zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    ElementUI中弹窗使用textarea原样显示SpringBoot后台带换行的StringBuilder内容
    Node搭建静态资源服务器时后缀名与响应头映射关系的Json文件
    Nodejs中搭建一个静态Web服务器,通过读取文件获取响应类型
    JS中怎样比较两个时分格式的时间大小
    ElementUI中对el-table的某一列的时间进行格式化
    MongoDb在Windows上的下载安装以及可视化工具的下载与使用
    Express中使用ejs新建项目以及ejs中实现传参、局部视图include、循环列表数据的使用
    FFmpeg-20160506-snapshot-bin
    FFmpeg-20160428-snapshot-bin
    FFmpeg-20160422-snapshot-bin
  • 原文地址:https://www.cnblogs.com/jhxxb/p/11596246.html
Copyright © 2011-2022 走看看