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的主要内容,如果未能解决你的问题,请参考以下文章