Java 解压缩zip和tar.gz

记录压缩有空目录报错的问题,

使用的是Apache的common-compress1.9

 

ZIP格式的解压缩

package com.lemo.rms.util;

import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * zip解压缩
 *
 * @author 杨小华
 * @version 1.0.0
 * @date 2018/1/22 17:40
 */
public class ZipUtil {
    private static final int BUFFER_SIZE = 1024;
    /**
     * 区分目录
     */
    private static final String PATH = "/";

    /**
     * zip压缩文件
     */
    public static void zip(String dir, String zipPath) {
        List<String> paths = getFiles(dir);
        compressFilesZip(paths.toArray(new String[paths.size()]), zipPath, dir);
    }

    /**
     * 递归取到当前目录所有文件
     */
    private static List<String> getFiles(String dir) {
        List<String> listFiles = new ArrayList<>();
        File file = new File(dir);
        File[] files = file.listFiles();
        String str = null;
        for (File f : files) {
            str = f.getAbsolutePath();
            listFiles.add(str);
            if (f.isDirectory()) {
                listFiles.addAll(getFiles(str));
            }
        }
        return listFiles;
    }

    /**
     * 文件名处理
     */
    private static String getFilePathName(String dir, String path) {
        String p = path.replace(dir + File.separator, "");
        p = p.replace("\\", "/");
        return p;
    }

    /**
     * 把文件压缩成zip格式
     *
     * @param files       需要压缩的文件
     * @param zipFilePath 压缩后的zip文件路径   ,如"D:/test/aa.zip";
     */
    private static void compressFilesZip(String[] files, String zipFilePath, String dir) {
        if (files == null || files.length <= 0) {
            return;
        }
        File zipFile = new File(zipFilePath);
        try (ZipArchiveOutputStream zaos = new ZipArchiveOutputStream(zipFile)) {
            zaos.setUseZip64(Zip64Mode.AsNeeded);
            //将每个文件用ZipArchiveEntry封装
            //再用ZipArchiveOutputStream写到压缩文件中
            for (String strFile : files) {
                File file = new File(strFile);
                if (file != null) {
                    String name = getFilePathName(dir, strFile);
                    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file, name);
                    zaos.putArchiveEntry(zipArchiveEntry);
                    if (file.isDirectory()) {
                        continue;
                    }
                    try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while ((len = is.read(buffer)) != -1) {
                            //把缓冲区的字节写入到ZipArchiveEntry
                            zaos.write(buffer, 0, len);
                        }
                        zaos.closeArchiveEntry();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            zaos.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 解压 zip 文件
     *
     * @param zipFile zip 压缩文件
     * @param destDir zip 压缩文件解压后保存的目录
     * @return 返回 zip 压缩文件里的文件名的 list
     */
    public static List<String> unZip(File zipFile, String destDir) {
        // 如果 destDir 为 null, 空字符串, 或者全是空格, 则解压到压缩文件所在目录
        if (StringUtils.isBlank(destDir)) {
            destDir = zipFile.getParent();
        }

        destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
        List<String> fileNames = new ArrayList<>();

        try (ZipArchiveInputStream is = new ZipArchiveInputStream(new BufferedInputStream(
                new FileInputStream(zipFile), BUFFER_SIZE));) {
            ZipArchiveEntry entry = null;
            while ((entry = is.getNextZipEntry()) != null) {
                fileNames.add(entry.getName());

                if (entry.isDirectory()) {
                    File directory = new File(destDir, entry.getName());
                    directory.mkdirs();
                } else {
                    try (OutputStream os = new BufferedOutputStream(new FileOutputStream(new File
                            (destDir,
                                    entry.getName())), BUFFER_SIZE);) {
                        IOUtils.copy(is, os);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return fileNames;
    }

    /**
     * 解压 zip 文件
     *
     * @param zipFilePath zip 压缩文件的路径
     * @param destDir     zip 压缩文件解压后保存的目录
     * @return 返回 zip 压缩文件里的文件名的 list
     */
    public static List<String> unZip(String zipFilePath, String destDir) throws Exception {
        File zipFile = new File(zipFilePath);
        return unZip(zipFile, destDir);
    }

    public static void main(String[] args) {
//        System.out.println(names);
        zip("D:\\nihao", "C:\\Users\\leimo\\Desktop\\nihao\\test.zip");
//        unZip("C:\\Users\\leimo\\Desktop\\nihao\\test.zip",
    }
}

GZIP格式解压缩

package com.lemo.rms.util;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 解压缩成tar.gz
 *
 * @author 杨小华
 * @version 1.0.0
 * @date 2018/1/22 14:45
 */
public class GZIPUtil {
    /**
     * tar后缀
     */
    private static final String TAR_SUFFIX = ".tar";
    /**
     * gz后缀
     */
    private static final String GZ_SUFFIX = ".gz";
    /**
     * 区分目录
     */
    private static final String PATH = "/";
    /**
     * 字节数组
     */
    private static final int BYTE_SIZE = 1024;


    /**
     * 归档
     *
     * @param srcFile 源文件
     * @return java.lang.String
     * @author 杨小华
     * @date 2018/1/22 15:38
     * @since 1.0.0
     */
    public static String archive(String srcFile) throws IOException {
        File file = new File(srcFile);

        TarArchiveOutputStream tos = new TarArchiveOutputStream(new FileOutputStream(file
                .getAbsolutePath() + TAR_SUFFIX));
        String basePath = file.getName();
        if (file.isDirectory()) {
            archiveDir(file, tos, basePath);
        } else {
            archiveHandle(tos, file, basePath);
        }
        tos.close();
        return file.getAbsolutePath() + TAR_SUFFIX;
    }

    /**
     * 目录归档
     *
     * @param dir      目录
     * @param taos     流
     * @param basePath 归档包内相对路径
     * @return void
     * @author 杨小华
     * @date 2018/1/22 15:40
     * @since 1.0.0
     */
    private static void archiveDir(File dir, TarArchiveOutputStream taos, String basePath) throws
            IOException {
        File[] files = dir.listFiles();
        for (File fi : files) {
            if (fi.isDirectory()) {
                archiveDir(fi, taos, basePath + File.separator + fi.getName());
            } else {
                archiveHandle(taos, fi, basePath);
            }
        }
    }

    /**
     * 具体归档处理(文件)
     *
     * @param taos     输出流
     * @param file     文件
     * @param basePath 文件路径
     * @return void
     * @author 杨小华
     * @date 2018/1/22 20:16
     * @since 1.0.0
     */
    private static void archiveHandle(TarArchiveOutputStream taos, File file, String basePath)
            throws IOException {
        TarArchiveEntry tEntry = new TarArchiveEntry(basePath + File.separator + file.getName());
        tEntry.setSize(file.length());

        taos.putArchiveEntry(tEntry);

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            byte[] buffer = new byte[BYTE_SIZE];
            int read = -1;
            while ((read = bis.read(buffer)) != -1) {
                taos.write(buffer, 0, read);
            }
        }
        //这里必须写,否则会失败
        taos.closeArchiveEntry();
    }


    /**
     * 把tar包压缩成gz
     *
     * @param path tar文件路径
     * @return java.lang.String
     * @author 杨小华
     * @date 2018/1/22 20:17
     * @since 1.0.0
     */
    public static String compressArchive(String path) throws IOException {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path))) {
            try (GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(new
                    BufferedOutputStream(new FileOutputStream(path + GZ_SUFFIX)))) {
                byte[] buffer = new byte[BYTE_SIZE];
                int read = -1;
                while ((read = bis.read(buffer)) != -1) {
                    gcos.write(buffer, 0, read);
                }
            }
        }
        return path + GZ_SUFFIX;
    }


    /**
     * 解压gz
     *
     * @return void
     * @author 杨小华
     * @date 2018/1/22 20:18
     * @since 1.0.0
     */
    public static void unCompressArchiveGz(String archive) throws IOException {

        File file = new File(archive);
        String finalName = null;

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            String fileName = file.getName().substring(0, file.getName().lastIndexOf("."));
            finalName = file.getParent() + File.separator + fileName;

            try (BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(finalName))) {
                GzipCompressorInputStream gcis = new GzipCompressorInputStream(bis);
                byte[] buffer = new byte[BYTE_SIZE];
                int read = -1;
                while ((read = gcis.read(buffer)) != -1) {
                    bos.write(buffer, 0, read);
                }
            }
        }
        unCompressTar(finalName);
    }

    /**
     * 解压tar
     *
     * @param finalName 文件路径
     * @return void
     * @author 杨小华
     * @date 2018/1/22 20:18
     * @since 1.0.0
     */
    private static void unCompressTar(String finalName) throws IOException {

        File file = new File(finalName);
        String parentPath = file.getParent();
        try (TarArchiveInputStream tais =
                     new TarArchiveInputStream(new FileInputStream(file))) {
            TarArchiveEntry tarArchiveEntry = null;
            while ((tarArchiveEntry = tais.getNextTarEntry()) != null) {
                String name = tarArchiveEntry.getName();
                File tarFile = new File(parentPath, name);
                if (!tarFile.getParentFile().exists()) {
                    tarFile.getParentFile().mkdirs();
                }
                try (BufferedOutputStream bos =
                             new BufferedOutputStream(new FileOutputStream(tarFile))) {
                    int read = -1;
                    byte[] buffer = new byte[BYTE_SIZE];
                    while ((read = tais.read(buffer)) != -1) {
                        bos.write(buffer, 0, read);
                    }
                }
            }
        }
        //删除tar文件
        file.delete();
    }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值