1、问题描述

公司项目有上传2g压缩包(zip、rar)功能,其中zip压缩包功能直接使用linux命令解压没有问题,在RAR解压时请求出现阻塞卡死的情况(直至情断请求超时,请求才会失败),查看服务器日志解压命令如下:

/usr/local/bin/unrar  X -o+ /data/temp/upload/xxx/2021/06/01/xxx_1622544204569.rar /data/temp/upload/xxx/2021/06/01

可以看出解压命令是没有错误的,于是去查看解压命令是否执行成功,找到解压目录,文件已经解压成功,如下图:

那么问题来了,为什么解压成功后,程序卡死在解压的代码(Process proc = Runtime.getRuntime().exec(cmd))??解压的方法如下:

/*** 采用命令行方式解压文件** @param zipFile 压缩文件* @param destDir 解压结果路径* @return*/public static boolean realExtract(String zipFile, String destDir) {// 解决路径中存在/..格式的路径问题destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();while (destDir.contains("..")) {String[] sepList = destDir.split("\\\\");destDir = "";for (int i = 0; i < sepList.length; i++) {if (!"..".equals(sepList[i]) && i < sepList.length - 1 && "..".equals(sepList[i + 1])) {i++;} else {destDir += sepList[i] + File.separator;}}}boolean bool = false;if (!FileUtil.exist(zipFile)) {return false;}if (!FileUtil.exist(destDir)) {FileUtil.mkdir(destDir);}//判断系统类型 开始调用命令行解压,参数-o+是表示覆盖的意思String cmdPath = "";String osName = System.getProperty("os.name");if (osName.contains("Window")) {cmdPath = "C:\\Program Files\\WinRAR\\WinRAR.exe";} else {cmdPath = "/usr/local/bin/unrar";}String cmd = cmdPath + " X -o+ " + zipFile + " " + destDir;System.out.println(cmd);try {Process proc = Runtime.getRuntime().exec(cmd);if (proc.waitFor() != 0) {if (proc.exitValue() == 0) {bool = false;}} else {bool = true;}} catch (Exception e) {log.error("解压失败:" + e.getMessage(), e);e.printStackTrace();}System.out.println("解压" + (bool ? "成功" : "失败"));return bool;}

问题分析

1、排除服务器权限问题(zip文件可解压成功,程序正常运行)
2、排除RAR解压命令问题(压缩包已经正常解压)
3、那现在就只剩下代码问题了由于系统是接手的项目,工具类在别的代码中也有引用,就直接拿过来使用,理所当然的认为代码没问题,于是开始找自己的问题(服务器目录权限、服务器上RAR版本等都没找到),准备在服务器上生成程序的dump日志,在查看服务器进程时发现了新大陆,如下图:![在这里插入图片描述](https://img-blog.csdnimg.cn/2021060213295942.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1aGFuY2hlbm1pbg==,size_16,color_FFFFFF,t_70#pic_center)

这个是解压RAR文件的进程,那问题可以确定了,也就是RAR解压没有关闭进程,那我看下JAVA执行linux命令方式:

Process proc = Runtime.getRuntime().exec(cmd)

百度下Process在线API:

重点我们看下面的图:

看到这里马上去对比代码:


这个缺少了杀死子进程的代码,那我们把代码修改下,下面是ZIP和RAR解压的工具类:

import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;import java.io.*;
import java.util.Enumeration;@Slf4j
public class ZipAndRarTools {/*** 解压Zip文件** @param zipFileName  需要解压缩的文件位置* @param descFileName 将文件解压到某个路径* @param isDel        是否删除压缩包* @throws IOException*/public static void unZip(String zipFileName, String descFileName, boolean isDel) throws IOException {System.out.println("文件解压开始...");String descFileNames = descFileName;if (!descFileNames.endsWith(File.separator)) {descFileNames = descFileNames + File.separator;}ZipFile zipFile = null;try {zipFile = new ZipFile(zipFileName);ZipEntry entry = null;String entryName = null;String descFileDir = null;byte[] buf = new byte[4096];int readByte = 0;@SuppressWarnings("rawtypes")Enumeration enums = zipFile.getEntries();while (enums.hasMoreElements()) {entry = (ZipEntry) enums.nextElement();entryName = entry.getName();descFileDir = descFileNames + entryName;if (entry.isDirectory()) {new File(descFileDir).mkdir();continue;} else {new File(descFileDir).getParentFile().mkdir();}File file = new File(descFileDir);OutputStream os = new FileOutputStream(file);InputStream is = zipFile.getInputStream(entry);while ((readByte = is.read(buf)) != -1) {os.write(buf, 0, readByte);}os.close();is.close();}System.out.println("文件解压成功!");} catch (Exception e) {System.out.println("文件解压失败!");e.printStackTrace();} finally {zipFile.close();}//删除压缩包if (isDel) {FileUtil.del(zipFileName);}}/*** 采用命令行方式解压文件** @param zipFile 压缩文件* @param destDir 解压结果路径* @return*/public static boolean realExtract(String zipFile, String destDir) {// 解决路径中存在/..格式的路径问题destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();while (destDir.contains("..")) {String[] sepList = destDir.split("\\\\");destDir = "";for (int i = 0; i < sepList.length; i++) {if (!"..".equals(sepList[i]) && i < sepList.length - 1 && "..".equals(sepList[i + 1])) {i++;} else {destDir += sepList[i] + File.separator;}}}boolean bool = false;if (!FileUtil.exist(zipFile)) {return false;}if (!FileUtil.exist(destDir)) {FileUtil.mkdir(destDir);}//判断系统类型 开始调用命令行解压,参数-o+是表示覆盖的意思String cmdPath = "";String osName = System.getProperty("os.name");if (osName.contains("Window")) {cmdPath = "C:\\Program Files\\WinRAR\\WinRAR.exe";} else {cmdPath = "/usr/local/bin/unrar";}String cmd = cmdPath + " X -o+ " + zipFile + " " + destDir;System.out.println(cmd);try {File file = new File(zipFile);String s;Process proc = Runtime.getRuntime().exec(cmd);BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));while((s = bufferedReader.readLine()) != null) {// 输出解压日志log.info(file.getName() + "-->" + s);}if (proc.waitFor() != 0) {if (proc.exitValue() == 0) {bool = false;}} else {bool = true;}// 关闭进程proc.destroy();} catch (Exception e) {log.error("解压失败:" + e.getMessage(), e);e.printStackTrace();}System.out.println("解压" + (bool ? "成功" : "失败"));return bool;}}

问题解决收工,记录问题希望能帮到大家,如有错误请指出,谢谢

java执行linux解压RAR命令程序阻塞/卡死相关推荐

  1. linux解压rar多层文件夹,linux rar 解压文件夹_rar文件夹

    原标题:linux rar 解压文件夹_rar文件夹 本经验主要针对linux中的解压缩进行讲解工具/原料linux电脑一台linux文件解压缩1目前 rar a jpg.rar *.jpg //ra ...

  2. linux的文件解压命令,linux解压命令(linux解压文件命令)

    在Linux指令下解压扩展名为".zip"的文件,最简单有用的方法是运用解压缩程序unzip来完结,详细的步骤如下: 装置unzip解压缩程序 通常情况下,Linux系统下都自带u ...

  3. linux服务器中如何解压分卷文件,Linux解压rar文件(unrar安装和使用,分卷解压)...

    windows平台很多压缩文档为rar文件,那么怎么做到Linux解压rar文件(unrar安装和使用)? 简单,centos5安装unrar即可. unrar安装 方法如下: wget  http: ...

  4. Linux解压rar文件(unrar安装和使用,分卷解压)

    windows平台很多压缩文档为rar文件,那么怎么做到Linux解压rar文件(unrar安装和使用)? 简单,centos5安装unrar即可. unrar安装 方法如下: wget  http: ...

  5. win压缩包linux解压软件,linux解压rar,zip压缩文件教程

    现在网上下载的文件很多都是rar,zip打包的,便于网络上传输,在Windows中只需要安装一个压缩软件那么加压rar,zip压缩文件就很方便了,那么在linux系统中呢,如何解压.zip和.rar文 ...

  6. linux解压tar命令

    linux解压 tar命令 tar命令 tar [-cxtzjvfpPN] 文件与目录 .... 参数: -c :建立一个压缩文件的参数指令(create 的意思): -x :解开一个压缩文件的参数指 ...

  7. linux解压文件命令

    linux解压文件命令: 1..tar 解包:tar xvf FileName.tar  -C [指定目录] 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压 ...

  8. linux解压覆盖命令

    linux解压覆盖命令 unzip -o  app.zip -o参数不提示覆盖同名文件

  9. linux 解压rar密码,linux下rar包的压缩与解压方案

    方法一: yum install unrar 方法二: 下载地址: 以最新的为准.对于Window下的常见压缩文件.zip和.rar,Linux也有相应的方法来解压它们: 1:对于.zip linux ...

最新文章

  1. junit5_使用junit做其他事情
  2. wkhtmltopdf
  3. 51nod 算法马拉松18 B 非010串 矩阵快速幂
  4. TCP 的连接建立:采用三报文握手
  5. SAP UI5 xml view content parse
  6. 我终于知道公司前端为啥不加班了…
  7. 工程计算软件_软件工程师的计算机基础理论知识体系
  8. 2021年跨专业/转行业学IT,还有前途吗?
  9. 地图学(何宗宜版)知识点整理
  10. android edittext 英文数字键盘,Adroid EditText限制输入数字与英文默认弹出数字键盘...
  11. QT 主线程子线程互相传值
  12. Arrays.sort排二维数组
  13. c51单片机音乐门铃C语言程序,基于51单片机的无线音乐门铃设计
  14. mac 爱普生打印机驱动_爱普生l201打印机驱动下载Mac版-爱普生L201驱动Mac版下载 V8.7.5-PC6苹果网...
  15. 报错JDBC Connection [com.mysql.jdbc.JDBC4Connection@184c65da] will not be managed by Spring
  16. php正三角,php打印正三角形
  17. 人工智能之华为云5G基站有AI,智能处理流量“潮汐”
  18. unity5.3 场景烘焙
  19. 关于OpenGL的天空盒的理解
  20. cass如何导入tif格式_CASS导入坐标文件的方法,一般人我不告诉他!-DAT文件

热门文章

  1. 三菱变频空调噪声大维修案例分析
  2. Leo-IM,开源好用的IM(基于Netty开发)
  3. 漫画 | 烂代码传奇
  4. Kinect for Windows SDK开发入门(十):手势识别 上:基本概念
  5. [BUAA OO Unit 3 HW12] 第三单元总结
  6. C#之富文本框控件出现“文件格式无效”的问题
  7. 原码, 反码, 补码 详解
  8. JS--闭包--渡一教育(视频笔记)
  9. BIEB六人行:网友给出小李的数据库查询慢的可能问题
  10. 机器数的定点表示与浮点表示