ZIP包压缩/解压

1、需求

北京市,按照村为单位,生成文件结构(包含市、区、镇,村/小区),最底层结构(村/小区)下面生成excel文件。

Excel生成参考:https://blog.csdn.net/u010286334/article/details/117107595

2、压缩

2.1、生成树状结构的

public class Tree {
    private String code;
    private String name;
    private List<String> urlList;
    private List<Tree> childs;

    public Tree() {
        childs = new ArrayList();
        childs.clear();
    }
}
public static Tree createTree(String[] areaCodes){
    Tree tree = new Tree();
    tree.setCode("中国");
    tree.setName("中国");
    Tree delegate = null;
    for (String areaCode : areaCodes) {
        int areaCount = areaCode.length();
        delegate = tree;
        int codeLength = 0;
        for (int i=0;i<areaCodeLevel;i++){
            codeLength += areaCodeLevelLength[i];
            String subCode = areaCode.substring(0, codeLength);
            //00或者000该层为空
            //90 省直辖县级行政规划
            if(shouldSkip(i, subCode)){
                continue;
            }
            
            String subName = findAreaName(subCode, codeLength);
            Tree existNode = findExistNode(delegate, subCode, subName);
            if(existNode!=null){
                delegate = existNode;
            } else if(!"00".equals(subCode)){
                Tree subTree = new Tree();
                subTree.setCode(subCode);
                subTree.setName(subName);
                delegate.addNode(subTree);
                delegate = subTree;
            }
        }
    }
    return tree;
}
private static String findAreaName(String subCode, int codeLength) {
    String code = subCode+StringUtils.repeat("0", CODE_LENGTH-codeLength);
    String name = codeNameMap.get(code);
    System.out.println(code+":"+name);
    return name;

}

private static Tree findExistNode(Tree delegate, String subCode, String subName) {
    for (Tree child : delegate.getChilds()) {
        if(subCode.equals(child.getCode())
        && subName.equals(child.getName())){
            return child;
        }
    }
    return null;
}

2.2、根据2.1中生成的数据结构构建zip文件

public static String generateFileFromTree( Tree tree, String format, boolean hasHead) throws Exception {

    // 压缩文件的路径不存在
    if (null == tree) {
        throw new Exception("文件树为空,无法进行压缩...");
    }
    // 用于存放压缩文件的文件夹
    String generateFile = "D:" + File.separator +"CompressFile";
    File compress = new File(generateFile);
    // 如果文件夹不存在,进行创建
    if( !compress.exists() ){
        compress.mkdirs();
    }

    // 目的压缩文件
    String generateFileName = compress.getAbsolutePath() + File.separator + "文件名称"+DateUtil.getDate()+"." + format;

    // 输出流
    FileOutputStream outputStream = new FileOutputStream(generateFileName);

    // 压缩输出流
    ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream));

    generateFileFromTree(zipOutputStream, tree.getChilds(), "");

    System.out.println("目的压缩文件生成位置:" + generateFileName);
    // 关闭 输出流
    zipOutputStream.close();

    return generateFileName;
}
/**
 * @param out  输出流
 * @param treeList 目标树
 * @throws Exception
 */
private static void generateFileFromTree(ZipOutputStream out, List<Tree> treeList, String dir) throws Exception {
    // 当前的是文件夹,则进行一步处理
    if (CollectionUtils.isNotEmpty(treeList)) {
        //循环将文件夹中的文件打包
        for (Tree tree : treeList) {

            String name = tree.getName();
            String subDir = dir  + "/" + name;
            //得到文件列表信息
            //将文件夹添加到下一级打包目录
            out.putNextEntry(new ZipEntry(subDir + "/"));

            subDir = subDir.length() == 0 ? "" : subDir + "/";
            //递归调用,生成各级文件夹
            generateFileFromTree(out, tree.getChilds(), subDir);
        }
    } else { // 当前是底层文件

        // 标记要打包的条目
        out.putNextEntry(new ZipEntry(dir+"明细"+FORMAT_INNER_EXCEL));

        // 输入流
        //TODO 查询业务数据
        List<ExportDto> list = new ArrayList<>(1);
        ExportDto exportDto = new ExportDto();
        exportDto.setBatchNo("123456788");
        list.add(exportDto);
        ByteArrayInputStream inputStream = ExcelUtil.write(list, ExportDto.class, "明细", 0);

        // 进行写操作
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) > 0) {
            out.write(bytes, 0, len);
        }
        // 关闭输入流
        inputStream.close();
    }
}

3、解压

    public static void decompressionFile(InputStream inputStream, Function<InputStream, Boolean> function) throws IOException {
        //zip读取压缩文件
        ZipInputStream in ;
        try {
            in = new ZipInputStream(inputStream, Charset.forName("gbk"));
        }catch (Exception e){
            in = new ZipInputStream(inputStream, Charset.forName("utf-8"));
        }

        ZipEntry zipEntry;
       
        while ((zipEntry=in.getNextEntry())!=null) {
            //如果是目录,不处理
            if (zipEntry.isDirectory()){
                System.err.println("当前路径为目录:"+zipEntry.getName());
            }else {
                //getNextEntry() 读取下一个ZIP文件条目,并将流定位在条目数据的开头。
                //这里in里面的文件流都是当前条目的文件数据, in.read读完就可以了
                File tmpFile = FileUtils.createTmpFile("tmp.xlsx");
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile));
                int len;
                byte[] buff = new byte[1024];
                while ((len = in.read(buff)) != -1) {
                    bos.write(buff, 0, len);
                }
                bos.close();
                //读取当前文件的数据流,
                //function单独处理当前文件的数据
                boolean result = function.apply(new FileInputStream(tmpFile));
                tmpFile.delete();
            }
        }
        //关闭流
        in.close();
    }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值