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

  • 相关阅读:
    js 生成32位UUID方法
    win10把控制声音改成和win7一样
    jQuery.inArray()方法
    在eclipse中安装activiti插件
    关于NOIP运输计划一题几种思路和若干种做法的研究
    该博客停止更新
    [CTSC2010]产品销售
    roi 学习轨迹
    「PA 2019」Szprotki i szczupaki
    LOJ576签到游戏
  • 原文地址:https://www.cnblogs.com/jhxxb/p/11596246.html
Copyright © 2011-2022 走看看