java读取多层zip压缩包中的xml文件内容

项目背景:系统数据对接,删量对方返回一个Base64的字符串,转文件后为zip,而且zip里面还会含有zip文件,最终才会存在xml文件记录有删量标识。

解决方法:
1.先将Base64转为文件。


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import static com.xzl.common.util.ReadXMLFromZIP.readZipFile;

/**
 * 文件与base64的互相转换操作
 */
public class Base64ToZIPFile {

    /**
     * 测试main
     *
     * @param args args
     */
    public static void main(String[] args) {
        Base64ToZIPFile t = new Base64ToZIPFile();
        try {
            // 拿到的Base64文件
            String ret = "UEsDBBQACAAIAAAAAA==";
            Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            t.decoderBase64File(ret, "C://" + milliSecond + ".zip", "C://");
            String zipfile_dir = "C://" + milliSecond + ".zip";
            try {
                // 读取xml
                readZipFile(zipfile_dir);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将文件转成base64 字符串
     *
     * @param path 文件路径
     * @return *
     * @throws Exception
     */
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return new BASE64Encoder().encode(buffer);
    }

    /**
     * 将base64字符解码保存文件
     *
     * @param base64Code 文件base64
     * @param targetPath 文件地址
     * @param catalogue  存放文件夹
     */
    public static void decoderBase64File(String base64Code, String targetPath, String catalogue)
            throws Exception {
        File file = new File(catalogue);
        if (file.exists() == false) {
            file.mkdirs();
        }
        byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code);
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();
    }

2.实现文件循环读取


import java.io.*;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * 阅读zip里的xml
 */
public class ReadXMLFromZIP {

    /**
     * 读取zip文件
     *
     * @param file 文件地址
     * @throws Exception 异常
     */
    public static void readZipFile(String file) throws Exception {
        readZipFile(new File(file));
    }

    /**
     * 循环解压读取xml文件信息
     *
     * @param file 文件
     * @throws Exception 异常
     */
    public static void readZipFile(File file) throws Exception {
        ZipFile zf = new ZipFile(file, Charset.forName("GBK"));
        InputStream in = new BufferedInputStream(new FileInputStream(file));
        ZipInputStream zis = new ZipInputStream(in);
        ZipEntry ze;
        while ((ze = zis.getNextEntry()) != null) {
            if (ze.isDirectory()) {
                System.err.println("true if this is a directory entry. A directory entry is!");
            } else {
                if (ze.getName().endsWith(".xml")) {
                    System.err.println("file - " + ze.getName() + " : " + ze.getSize() + " bytes");
                    // 不解压直接读取size为-1
                    if (ze.getSize() == -1) {
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while (true) {
                            int bytes = zis.read();
                            if (bytes == -1) {
                                break;
                            }
                            baos.write(bytes);
                        }
                        baos.close();
                        System.out.println(String.format("Name:%s,Content:%s", ze.getName(), new String(baos.toByteArray())));
                    } else {
                        // ZipEntry的size正常
                        byte[] bytes = new byte[(int) ze.getSize()];
                        zis.read(bytes, 0, (int) ze.getSize());
                        System.out.println(String.format("Name:%s,Content:%s", ze.getName(), new String(bytes)));
                    }
                } else if (ze.getName().endsWith("zip")) {
                    //判断是否为压缩包,若是则将其解压出再读取
                    String fileName = file.getName().substring(0, file.getName().lastIndexOf("."));
                    File temp = new File(file.getParent() + File.separator + fileName + File.separator + ze.getName());
                    if (!temp.getParentFile().exists()) {
                        temp.getParentFile().mkdirs();
                    }
                    OutputStream os = new FileOutputStream(temp);
                    通过ZipFile的getInputStream方法拿到具体的ZipEntry的输入流
                    InputStream is = zf.getInputStream(ze);
                    int len;
                    while ((len = is.read()) != -1) {
                        os.write(len);
                    }
                    os.close();
                    is.close();
                    // 递归调取解压
                    readZipFile(temp.getPath());
                }
            }
        }
        zis.closeEntry();
        zis.close();
        zf.close();
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lovme_du

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值