Java压缩和解压缩

  • 压缩和解压缩依赖
  • 关于Java解压Zip文件的java.lang.IllegalArgumentException:MALFORMED报错问题。
  • 解压缩代码
    • Zip解压缩
    • War解压缩
    • Tar解压缩
    • TarGz解压缩
    • Rar解压缩

压缩和解压缩依赖

导入pom依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId>
</dependency>

rar的pom依赖为

<dependency><groupId>com.github.junrar</groupId><artifactId>junrar</artifactId>
</dependency>

关于Java解压Zip文件的java.lang.IllegalArgumentException:MALFORMED报错问题。

java报错

java.lang.IllegalArgumentException:MALFORMEDat java.util.zip.ZipCoder.toString(ZipCoder.toString:58)......

首先在网上查了下这个异常的原因, 都说是因为编码的问题, 要求将UTF-8改成GBK就可以了。
然后找到ZipCoder.toString方法的58行

    String toString(byte[] ba, int length) {CharsetDecoder cd = decoder().reset();int len = (int)(length * cd.maxCharsPerByte());char[] ca = new char[len];if (len == 0)return new String(ca);// UTF-8 only for now. Other ArrayDeocder only handles// CodingErrorAction.REPLACE mode. ZipCoder uses// REPORT mode.if (isUTF8 && cd instanceof ArrayDecoder) {int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);if (clen == -1)    // malformedthrow new IllegalArgumentException("MALFORMED");return new String(ca, 0, clen);}ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);CharBuffer cb = CharBuffer.wrap(ca);CoderResult cr = cd.decode(bb, cb, true);if (!cr.isUnderflow())throw new IllegalArgumentException(cr.toString());cr = cd.flush(cb);if (!cr.isUnderflow())throw new IllegalArgumentException(cr.toString());return new String(ca, 0, cb.position());}

这里只有UTF-8才会进入if逻辑才会抛出异常?果然如网上所说, 将编码格式改为GBK即可。
ZipCoder这个是src.zip包中的, 既然这里做了校验当然会有它的道理。
但是,单纯的改为GBK来解决这个bug显然是不合理的。
于是又在网上找,将原来写的
ZipInputStream 改为 ZipArchiveInputStream ;
ZipEntry 改为 ZipArchiveEntry ;
zipin.getNextEntry() 改为 zipin.getNextZipEntry() 可解决问题。

解压缩代码

Zip解压缩

public class ZipUtil {private static final Logger log = LoggerFactory.getLogger(ZipUtil.class);public static void doUnzip(String fileName) throws Exception {File f = new File(fileName);String fileDir = f.getParent();log.debug("path is {}", fileDir);doUnzip(fileName, fileDir);}public static void doUnzip(String fileName, String dir) throws Exception {// 文件输入流try ( FileInputStream fi = new FileInputStream(fileName);) {doUnzip(fi, dir);}}public static void doUnzip(File file, String dir) throws Exception {// 文件输入流try ( FileInputStream fi = new FileInputStream(file);) {doUnzip(fi, dir);}}public static void doUnzip(InputStream fi, final String dir) throws Exception {try ( // 输入流检查CheckedInputStream csi = new CheckedInputStream(fi, new Adler32()); // 输入流压缩ZipArchiveInputStream zipin = new ZipArchiveInputStream(csi)) {ZipArchiveEntry ze;while ((ze = zipin.getNextZipEntry()) != null) {String name = ze.getName();log.debug("name is {}", name);File newFile = UtilFile.newFileWithCheck(dir, name);if (ze.isDirectory()) {if (!newFile.exists()) {newFile.mkdirs();}} else {if (!newFile.getParentFile().exists()) {newFile.getParentFile().mkdirs();}//newFile.createNewFile();try ( OutputStream out = new FileOutputStream(newFile);) {UtilFile.copyNoClose(zipin, out);}}}}}//检查slip漏洞public static final File newFileWithCheck(final String destinationDirName, final String name) throws IOException {File destinationDir = new File(destinationDirName);return newFileWithCheck(destinationDir, name);}public static final File newFileWithCheck(final File destinationDir, final String name) throws IOException {File destFile = new File(destinationDir, name);String destDirPath = destinationDir.getCanonicalPath();String destFilePath = destFile.getCanonicalPath();if (!destFilePath.startsWith(destDirPath + File.separator)) {throw new IOException("Entry is outside of the target dir: " + name);}return destFile;}public final static void copyNoClose(InputStream in, OutputStream out) throws IOException {byte[] buffer = new byte[BufferSize << 1];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}out.flush();}
}

War解压缩

public class WarUtil {private static final Logger logger = LoggerFactory.getLogger(WarUtil.class);/*** war文件格式的过滤器*/private static FileNameExtensionFilter filter = new FileNameExtensionFilter("WAR压缩文件(*.war)", "war");/*** 解压缩war包* @param filePath:war包所在路径,包含本身文件名* @param destPath:解压缩到路径* */public static void unCompressWar(String filePath, String destPath) throws IOException, ArchiveException {unCompressWar(new FileInputStream(filePath),destPath);}/*** 解压缩war包* @param srcFile:war包文件* @param destPath:解压缩到路径* */public static void unCompressWar(File srcFile, String destPath) throws IOException, ArchiveException {unCompressWar(new FileInputStream(srcFile),destPath);}/*** 解压缩war包* @param warInputStream:war包输入流* @param destPath:解压缩到路径* */public static void unCompressWar(InputStream warInputStream, String destPath) throws IOException, ArchiveException {ArchiveInputStream in = null;try {BufferedInputStream bufferedInputStream = new BufferedInputStream(warInputStream);in = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.JAR, bufferedInputStream);JarArchiveEntry entry = null;logger.info("解压文件: 到 {}", destPath);while ((entry = (JarArchiveEntry) in.getNextEntry()) != null) {if (entry.isDirectory()) {File newFile = UtilFile.newFileWithCheck(destPath,  entry.getName());if(!newFile.exists()){logger.info("文件夹{}不存在,创建.",newFile.getAbsolutePath());newFile.mkdir();}if(newFile.exists() && !newFile.isDirectory()){logger.info("不能解压文件{}到{},此文件己存在",entry.getName(),newFile.getAbsolutePath());}} else {File outFile = UtilFile.newFileWithCheck(destPath,  entry.getName());if(!outFile.getParentFile().exists()){logger.info("文件夹{}不存在,创建.",outFile.getParentFile().getAbsolutePath());outFile.getParentFile().mkdirs();}logger.info("解压{} 至 {}",entry.getName(),outFile.getAbsolutePath());OutputStream out = FileUtils.openOutputStream(outFile);IOUtils.copy(in, out);out.close();}}} catch (FileNotFoundException e) {logger.error("未找到war文件");throw new FileNotFoundException("未找到war文件");} catch (ArchiveException e) {logger.error("不支持的压缩格式");throw new ArchiveException("不支持的压缩格式");} catch (IOException e) {logger.error("文件写入发生错误");throw new IOException("文件写入发生错误");}finally{in.close();logger.info("解压结束.");}}public FileNameExtensionFilter getFileFilter() {return filter;}
}

Tar解压缩

public class TarUtil {/**解压缩tar文件* */public static void unCompressTar(String srcfilePath, String destpath)throws IOException {unCompressTar(new FileInputStream(srcfilePath), destpath);}/**解压缩tar文件* */public static void unCompressTar(File srcfile, String destpath)throws IOException {unCompressTar(new FileInputStream(srcfile), destpath);}/**解压缩tar文件* */public static void unCompressTar(InputStream inputStream, String destPath)throws IOException {BufferedInputStream bis = new BufferedInputStream(inputStream);TarArchiveInputStream taris = new TarArchiveInputStream(bis);TarArchiveEntry entry = null;while ((entry = taris.getNextTarEntry()) != null) {File newFile = UtilFile.newFileWithCheck(destPath,  entry.getName());if (entry.isDirectory()) {newFile.mkdirs();} else {/** 父目录不存在则创建*/File parent = newFile.getParentFile();if (!parent.exists()) {parent.mkdirs();}FileOutputStream fos = new FileOutputStream(newFile);BufferedOutputStream bos = new BufferedOutputStream(fos);int len;byte[] buf = new byte[1024];while ((len = taris.read(buf)) != -1) {bos.write(buf, 0, len);}bos.flush();bos.close();}}taris.close();}
}

TarGz解压缩

public class TarGzUtil {private static final Logger logger = LoggerFactory.getLogger(TarGzUtil.class);/*** 解压tar.gz格式的压缩包为tar压缩包* @param sourcePath 待解压文件路径* @param destPath 解压路径*/public static void unCompressTarGz(String sourcePath, String destPath) throws IOException {long start = System.currentTimeMillis();File sourceFile = new File(sourcePath);logger.info("start to unpack tar.gz file, file name:{}", sourceFile.getName());unCompressTarGz(sourceFile, destPath);logger.info("finish unpack tar.gz file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);}/*** 解压tar.gz格式的压缩包为tar压缩包* @param sourceFile 待解压文件* @param destPath 解压路径*/public static void unCompressTarGz(File sourceFile, String destPath) throws IOException {long start = System.currentTimeMillis();logger.info("start to unpack tar.gz file, file name:{}", sourceFile.getName());unCompressTarGz(new FileInputStream(sourceFile), destPath);logger.info("finish unpack tar.gz file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);}/*** 解压tar.gz格式的压缩包为tar压缩包* @param inputStream 待解压文件输入流* @param destPath 解压路径*/public static void unCompressTarGz(InputStream inputStream, String destPath) throws IOException {logger.info("start to unpack tar.gz fileInputStream");try (FileInputStream fileInputStream = (FileInputStream) inputStream;GzipCompressorInputStream gzipCompressorInputStream = new GzipCompressorInputStream(fileInputStream);TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipCompressorInputStream, "UTF-8")) {TarArchiveEntry entry;while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {if (entry.isDirectory()) {continue;}File curFile = UtilFile.newFileWithCheck(destPath, entry.getName());File parent = curFile.getParentFile();if (!parent.exists()) {parent.mkdirs();}try (FileOutputStream outputStream = new FileOutputStream(curFile)) {IOUtils.copy(tarArchiveInputStream, outputStream);}}}logger.info("finish unpack tar.gz file");}
}

Rar解压缩

rar解压缩暂不支持高版本的解压缩

public class RarUtil {private static final Logger logger = LoggerFactory.getLogger(RarUtil.class);/*** 解压rar格式的压缩包** @param sourcePath 待解压文件* @param targetPath 解压路径*/public static void unCompressRar(String sourcePath, String targetPath) {//File sourceFile = FileUtil.validateSourcePath(sourcePath);unCompressRar(new File(sourcePath), targetPath);}public static void unCompressRar(File sourceFile, String targetPath) {//校验解压地址是否存在// FileUtil.validateTargetPath(targetPath);logger.info("start to unpack rar file, file name:{}", sourceFile.getName());long start = System.currentTimeMillis();System.out.println("absolute path is ============= " + sourceFile.getAbsolutePath());try (Archive archive = new Archive(new FileInputStream(sourceFile))) {FileHeader fileHeader = archive.nextFileHeader();while (fileHeader != null) {//如果是文件夹if (fileHeader.isDirectory()) {fileHeader = archive.nextFileHeader();continue;}//防止文件名中文乱码问题的处理File out = new File(String.format("%s%s%s", targetPath, File.separator, fileHeader.getFileName()));if (!out.exists()) {if (!out.getParentFile().exists()) {out.getParentFile().mkdirs(); //相对路径可能多级,可能需要创建父目录.}out.createNewFile();}try (FileOutputStream os = new FileOutputStream(out)) {archive.extractFile(fileHeader, os);} catch (RarException e) {logger.error("unpack rar throw exception, filename:{}, e:{}", sourceFile.getName(), e);}fileHeader = archive.nextFileHeader();}} catch (FileNotFoundException e) {e.printStackTrace();} catch (RarException e) {logger.error("unpack rar throw exception, file name:{}, e:{}", sourceFile.getName(), e);e.printStackTrace();} catch (IOException e) {e.printStackTrace();}logger.info("finish unpack rar file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);}
}

Java解压文件Zip,War,Tar,TarGz格式相关推荐

  1. java zip malformed_关于Java解压文件的一些坑及经验分享(MALFORMED异常)

    关于Java解压文件的一些坑及经验分享 就在本周, 测试人员找到我说现上的需求文档(zip格式的)无法预览了, 让我帮忙看看怎么回事. 这个功能也并不是我做的, 于是我便先看看线上日志有没有什么错误, ...

  2. java 解压文件_java实现解压zip文件,(亲测可用)!!!!!!

    项目结构: Util.java内容: package com.cfets.demo; import java.io.File; import java.io.FileOutputStream; imp ...

  3. java解压文件、复制文件、删除文件代码示例

    文章目录 删除文件: 创建目录 拷贝文件 解压zip文件 解压文件时,可以采用多线程的方式,下面上代码: 创建类 @Slf4j public class FileOperation {private ...

  4. linux java解压文件怎么打开,linux下面的解压缩文件的命令

    尝试去好好用linux.新手起步.   这边只会提到我用过的.其他相关的以后我用到了我会补充的.如果有错欢迎指正 注:1.c-创建-create 2.v-复杂输出 3.f-文件-file 4.x-解压 ...

  5. 问题解决:Java解压文件时报错:MALFORMED

    在解压文件的时候报错,原因是压缩文件中有中文:导致错误,解决办法是设置编码: ZipFile zipOutFile = new ZipFile(zipFile,Charset.forName(&quo ...

  6. java解压_Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)

    JDK中自带的ZipOutputStream在压缩文件时,如果文件名中有中文,则压缩后的 zip文件打开时发现中文文件名变成乱码. 解决的方法是使用apache-ant-zip.jar包(见附件)中的 ...

  7. Linux压缩文件与解压文件(*.zip)

    1.把/home目录下面的mydata目录压缩为mydata.zip zip -r mydata.zip mydata #压缩mydata目录 2.把/home目录下面的mydata.zip解压到my ...

  8. Java解压文件的一些坑及经验分享(MALFORMED异常)

    一.错误如下: java.lang.IllegalArgumentException: MALFORMEDat java.util.zip.ZipCoder.toString(ZipCoder.jav ...

  9. linux 解压文件zip格式

    在终端下载zip解压包 下载好之后执行  unzip  文件名.zip (如果不知道怎么下载,直接执行解压语句,终端会提示安装语句)

最新文章

  1. SQLServer------插入数据时出现IDENTITY_INSERT错误
  2. getChars的用法
  3. C指针原理(31)-Ncurses-文本终端的图形
  4. access数据类型百度百科_Day 7 基本数据类型
  5. 微软将推出桌面虚拟化软件
  6. vue接收json数据_Vue之使用ajax获取json数据,并用v-for循环显示在表格中
  7. regini.exe使用方法
  8. SpringBoot 计划任务
  9. (37)VHDL实现RS触发器
  10. ide在控制台输入编译命令_编译原理、VC的构成以及用VC2010建立C程序
  11. Linux 系统-----vim命令详解
  12. (学习笔记)图像处理——Retinex增强
  13. Android 获取圆角图标bitmap黑色背景问题解决
  14. EverEdit 4.2.0.4457 免安装已激活 x64
  15. 【论文笔记】2022-CVPR-深度估计
  16. cad管线交叉怎么画_CAD角度怎么画?我来告诉你!
  17. 高性能RTMP推流服务器软件EasyDSS如何支持推流摄像机推流直播进行云端录像存储及计划保存
  18. 查看google浏览器里的证书
  19. 跑象科技CEO 卢山巍:大数据具有“黑魔法”魅力
  20. Python 3 爬虫之批量下载字帖图片

热门文章

  1. 胡润百富今日发布《2020胡润中国最具影响力财经媒体榜》的阅读感受
  2. Kali aircrack-ng 暴破wifi
  3. 【数学】方差/标准差的各种估计辨析
  4. ANSYS Workbench结构分析网格划分的总体控制和局部控制解析
  5. UEFI 开发学习 - LVGL在EDK2上的移植
  6. Field userClient in com.xxx.UserController required a bean of type“com.xxx“that could not be found.
  7. 福昕阅读器(Foxit福昕阅读器(Foxit Reader) 3.0 Build 1506 注册方法
  8. 采用开源工具学习51单片机
  9. Python程序设计实验——3.检测手机号真实性
  10. Android11.0 修改设备名、型号、厂商