通过jdk1.7nio实现对zip包的压缩和解压

将目标目录打包压缩到zip包中,通过jdk1.7的Files.walkFileTree原理实现,参考代码如下:

/**
     * 将目标文件或者文件夹压缩到zip中
     * 
     * @param zipOutpusStream zip输出流
     * @param target 需要压缩的目标目录
     * @param ignoreEntryNames 忽略压缩目录
     * @throws IOException IOException
     */
    public static void zip(OutputStream zipOutpusStream, Path target, List<Path> ignoreEntryNames) throws IOException {
        ZipOutputStream out = new ZipOutputStream(zipOutpusStream);
        Files.walkFileTree(target, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
            new ZipDirectoryVisitor(out, target, ignoreEntryNames));
        if (out != null) {
            out.close();
        }
    }
package xxx.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * ZIP包输出访问器
 * 
 * @author 许畅
 * @since JDK1.7
 * @version 2019年4月8日 许畅 新建
 */
public class ZipDirectoryVisitor extends SimpleFileVisitor<Path> {
    
    /** zip输出流 */
    private ZipOutputStream out;
    
    /** zip包中存储相对路径 */
    private Path relativePath;
    
    /** zip包中需要忽略的entry名称 */
    private List<Path> ignoreEntryNames;
    
    /**
     * 构造方法
     * 
     * @param out ZIP输出流
     * @param relativePath ZIP包存储相对路径
     */
    public ZipDirectoryVisitor(ZipOutputStream out, Path relativePath) {
        setOut(out);
        setRelativePath(relativePath);
    }
    
    /**
     * 构造方法
     * 
     * @param out ZIP输出流
     * @param relativePath ZIP包存储相对路径
     * @param ignoreEntryNames zip包中需要忽略的entry名称
     */
    public ZipDirectoryVisitor(ZipOutputStream out, Path relativePath, List<Path> ignoreEntryNames) {
        setOut(out);
        setRelativePath(relativePath);
        setIgnoreEntryNames(ignoreEntryNames);
    }
    
    /**
     * 访问文件
     * 
     * @param file 文件路径
     * @param attributes 属性
     * @return FileVisitResult
     * @throws IOException IO异常
     */
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
        Path entryName = relativePath.relativize(file);
        if (ignoreEntryNames == null || !ignoreEntryNames.contains(entryName)) {
            addEntry(file.toFile(), entryName);
        }
        return FileVisitResult.CONTINUE;
    }
    
    @Override
    public FileVisitResult preVisitDirectory(Path directory, BasicFileAttributes attributes) throws IOException {
        return FileVisitResult.CONTINUE;
    }
    
    /**
     * 添加ZIP包的entry
     * 
     * @param inFile ZIP输入文件
     * @param entryName ZIP的文件名
     * @throws IOException IOException
     */
    private void addEntry(File inFile, Path entryName) throws IOException {
        ZipEntry entry = new ZipEntry(entryName.toString());
        out.putNextEntry(entry);
        
        int len = 0;
        byte[] buffer = new byte[1024];
        FileInputStream fis = new FileInputStream(inFile);
        while ((len = fis.read(buffer)) > 0) {
            out.write(buffer, 0, len);
            out.flush();
        }
        out.closeEntry();
        fis.close();
    }
    
    /**
     * @return 获取 out属性值
     */
    public ZipOutputStream getOut() {
        return out;
    }
    
    /**
     * @param out 设置 out 属性值为参数值 out
     */
    public void setOut(ZipOutputStream out) {
        this.out = out;
    }
    
    /**
     * @return 获取 relativePath属性值
     */
    public Path getRelativePath() {
        return relativePath;
    }
    
    /**
     * @param relativePath 设置 relativePath 属性值为参数值 relativePath
     */
    public void setRelativePath(Path relativePath) {
        this.relativePath = relativePath;
    }
    
    /**
     * @return 获取 ignoreEntryNames属性值
     */
    public List<Path> getIgnoreEntryNames() {
        return ignoreEntryNames;
    }
    
    /**
     * @param ignoreEntryNames 设置 ignoreEntryNames 属性值为参数值 ignoreEntryNames
     */
    public void setIgnoreEntryNames(List<Path> ignoreEntryNames) {
        this.ignoreEntryNames = ignoreEntryNames;
    }
    
}

将zip包解压到指定文件夹,直接通过jdk io实现,参考代码如下:

/**
     * 将zip包解压到目标目录
     * 
     * @param zipInputstream zip输入流
     * @param destDir 需要解压的目标目录
     * @param ignorePatterns 忽略解压目录
     * @throws IOException IOException
     */
    public static void unzip(InputStream zipInputstream, Path destDir, List<String> ignorePatterns) throws IOException {
        if (!Files.exists(destDir)) {
            Files.createDirectories(destDir);
        }
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(zipInputstream);
        ZipEntry zipEntry = zis.getNextEntry();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        while (zipEntry != null) {
            if (isIgnoreMatch(ignorePatterns, zipEntry.getName(), antPathMatcher)) {
                zipEntry = zis.getNextEntry();
                continue;
            }
            Path destFile = destDir.resolve(zipEntry.getName());
            if (zipEntry.isDirectory()) {
                if (!Files.exists(destFile)) {
                    Files.createDirectories(destFile);
                }
            } else {
                if (!Files.exists(destFile) && !Files.exists(destFile.getParent())) {
                    // 创建上级文件夹
                    Files.createDirectories(destFile.getParent());
                }
                FileOutputStream fos = new FileOutputStream(destFile.toFile());
                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
                zipEntry = zis.getNextEntry();
            }
        }
        zis.closeEntry();
        zis.close();
    }
 /**
     * @param ignorePatterns 忽略正则
     * @param entryName 目录名称
     * @param antPathMatcher AntPathMatcher
     * @return 是否忽略
     */
    private static boolean isIgnoreMatch(List<String> ignorePatterns, String entryName, AntPathMatcher antPathMatcher) {
        if (ignorePatterns != null) {
            for (String ignorePattern : ignorePatterns) {
                if (antPathMatcher.match(ignorePattern, entryName)) {
                    return true;
                }
            }
        }
        return false;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值