项目背景:系统数据对接,删量对方返回一个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 mon.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 {// 读取xmlreadZipFile(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为-1if (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();}}