zoukankan      html  css  js  c++  java
  • 文件压缩工具类

    解决了中文乱码问题

    导入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;
        }
    
    }
    
    
  • 相关阅读:
    uva 10129
    年化利率
    house买房原理,2019,第一版
    car二手车购买原理
    car购车翻译篇
    car配置篇
    健身原理
    语法学习,从句
    语法学习,简单语句
    名词解释
  • 原文地址:https://www.cnblogs.com/qiaozhuangshi/p/11198157.html
Copyright © 2011-2022 走看看