首页 > 其他 > 详细

文件压缩工具类

时间:2019-07-16 23:57:29      阅读:151      评论:0      收藏:0      [点我收藏+]

解决了中文乱码问题

导入apache的jar包

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant</artifactId>
    <version>1.10.5</version>
</dependency>

代码如下

package com.dist.util;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

/**
 * 压缩文件 无中文乱码问题
 * @author qyp
 * 2018-3-24 下午05:12:30
 */
public class ZipUtils {

    private final static Logger logger = LoggerFactory.getLogger(ZipUtils.class);

    public static void main(String[] args) throws Exception {

        File rootFile = new File("E:\\temp\\test");

        List<InputStream> ins = new ArrayList<>();
        List<String> names = new ArrayList<>();
        List<String> namePaths = Lists.newArrayList();
        File[] list = rootFile.listFiles();
        for (File f : list) {
            names.add(f.getName());
            namePaths.add(f.getAbsolutePath());
            ins.add(new FileInputStream(f));
        }
        //zipByInStream("e:\\temp\\a.zip", ins, names);
        //zipByFileNames("e:\\temp\\a.zip", namePaths);
        zipByFiles("e:\\temp\\a.zip", Arrays.asList(list));
    }

    /**
     * 将文件的流集合代表的文件压缩成一个压缩包并保存到指定位置
     * @param savePath  生成的压缩包的位置
     * @param inputStreams 文件流集合
     * @param names     文件名称集合
     * @throws Exception 如果文件路径不存在或者压缩失败,那么久会抛异常
     */
    public static void zipByInStream(String savePath, List<InputStream> inputStreams, List<String> names) throws Exception {
        ZipOutputStream zos = getOutPutStream(savePath);
        BufferedReader bufr = null;
        // 缓存输出流
        try (BufferedOutputStream out = new BufferedOutputStream(zos)) {
            for (int i = 0, len = inputStreams.size(); i < len; i++) {
                //添加一个条目到压缩包
                zos.putNextEntry(new ZipEntry(names.get(i)));
                int c;
                // StandardCharsets.ISO_8859_1 防止文件内容乱码
                bufr = new BufferedReader(new InputStreamReader(inputStreams.get(i), StandardCharsets.ISO_8859_1));
                while ((c = bufr.read()) != -1) {
                    out.write(c);
                }
                out.flush();
                if (bufr != null) {
                    bufr.close();
                }
            }
        } catch (IOException r) {
            throw new RuntimeException("文件压缩失败");
        } finally {
            if (bufr != null) {
                bufr.close();
            }
        }
    }

    /**
     * 根据文件名集合获取文件并压缩
     * @param savePath          保存的压缩文件路径
     * @param targetFileNames   被压缩的文件名集合(全路径)
     * @throws Exception
     */
    public static void zipByFileNames(String savePath, List<String> targetFileNames) throws Exception {
        Function<Object, String> nameFun = (obj) -> getFileName((String) obj);
        Function<Object, InputStream> inFun = (obj) -> {
            try {
                return new FileInputStream((String) obj);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        };
        zipFile(savePath, targetFileNames, nameFun, inFun);
    }

    /**
     * 根据文件集合生成压缩文件
     * @param savePath      保存的压缩文件路径
     * @param targetFiles   被压缩的文件集合
     * @throws Exception
     */
    public static void zipByFiles(String savePath, List<File> targetFiles) throws Exception {
        Function<Object, String> nameFun = (obj) -> ((File)obj).getName();
        Function<Object, InputStream> inFun = (obj) -> {
            try {
                return new FileInputStream((File) obj);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        };
        zipFile(savePath, targetFiles, nameFun, inFun);
    }

    /**
     * 压缩文件
     * @param savePath  保存的压缩文件路径
     * @param targets   被压缩的对象(文件名集合(全路径),或者文件集合)
     * @param nameFun   获取文件名的Function对象
     * @param inFun     获取InputStream的Function对象
     * @throws Exception
     */
    private static void zipFile(String savePath, List<?> targets, Function<Object, String> nameFun, Function<Object, InputStream> inFun) throws Exception {
        ZipOutputStream zos = getOutPutStream(savePath);
        BufferedReader bufr = null;
        // 缓存输出流
        try (BufferedOutputStream out = new BufferedOutputStream(zos)) {
            for (int i = 0, len = targets.size(); i < len; i++) {
                zos.putNextEntry(new ZipEntry(nameFun.apply(targets.get(i))));
                int c;
                bufr = new BufferedReader(new InputStreamReader(inFun.apply(targets.get(i)), StandardCharsets.ISO_8859_1));
                while ((c = bufr.read()) != -1) {
                    out.write(c);
                }
                out.flush();
                if (bufr != null) {
                    bufr.close();
                }
            }
            logger.info("成功压缩{}个文件,保存地址为【{}】", targets.size(), savePath);
        } catch (IOException r) {
            throw new RuntimeException("文件压缩失败");
        } finally {
            if (bufr != null) {
                bufr.close();
            }
        }
    }

    /**
     * 获取apache的ZipOutputStream流
     * @param savePath 保存压缩文件的路径
     * @return
     * @throws FileNotFoundException 如果保存路径不存在,那么将会抛异常
     */
    private static ZipOutputStream getOutPutStream(String savePath) throws FileNotFoundException {
        //输出的压缩原始文件流fileDir + "\\" + "详情.zip"
        FileOutputStream f = new FileOutputStream(new File(savePath));
        // 计算和校验文件
        CheckedOutputStream csum = new CheckedOutputStream(f, new CRC32());
        // 输出的压缩文件流
        ZipOutputStream zos = new ZipOutputStream(csum);
        zos.setComment("dist文件压缩流");
        //设置压缩工具右边的文字编码  防止右边的说明文字乱码
        zos.setEncoding(System.getProperty("sun.jnu.encoding"));
        return zos;
    }

    /**
     * 获取文件名
     * @param filePath
     * @return
     */
    public static String getFileName(String filePath) {
        int idx = StringUtils.lastIndexOf(filePath, File.separator);
        if (idx != -1) {
            return StringUtils.substring(filePath, idx + 1);
        }
        return filePath;
    }

}

文件压缩工具类

原文:https://www.cnblogs.com/qiaozhuangshi/p/11198157.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!