1 问题描写叙述

Java Web 后端下载了一个经特殊算法压缩的 zip 文件,由于不能採用 java 本身自带的解压方式,必须採用 7Zip 来解压。所以,提到了本文中在 java web 后端调用外部 7zip exe 来解压文件的问题。

2 主要实现

2.1 定义缓冲区类

class StreamGobbler extends Thread {
InputStream is;
String type; public StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
} public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe){
ioe.printStackTrace();
}
}
}

2.2 运行外部 exe 流程

String[] cmd = {
"7za.exe",
"x",
zipPath,
"-o" + outputPath
}; Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd); // 监听出错信息
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR"); // 监听输出信息
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT"); // 启动监听输入
errorGobbler.start();
outputGobbler.start(); // 确保 Runtime.exec 进程运行完成
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);

3 重点解决

3.1 Process.waitFor 在 tomcat 中运行时,卡死状态

3.1.1 问题原因

一定要在调用Process.waitFor()前将程序的stdout和stderr都读完,否则就有可能由于pipe的缓冲区不够,被调用的系统命令堵塞在标准输出和标准错误输出上。Windows由于这个缓冲区的默认值比較小更easy出现这个问题。





须要注意读取程序的stdout和stderr都是堵塞的操作,这意味着必须在两个线程里分别读取,而不是在一个线程里一次读取,否则还是有可能出现堵塞的情况。





[http://www.dongliu.net/post/496142]

3.1.2 其它推測

1. 程序主进程会等待process一定的时间,可是时间非常少,可能process根本无法完毕工作就结束了。 因此,针对使用较长时间做工作的process,就须要调用waitFor方法。 该方法会引起当前Thread等待,直到process中断。 [http://ccchhhlll1988-163-com.iteye.com/blog/1901497]





2. 可能是由于在 tomcat 中启动了一个进程,可是没有权限来杀死这个进程,所以,一直卡在这个界面

4 其它

4.1 用 Java 自带的解压库

java.util.zip





因为算法不一致,解压时提示: “invalid CEN header(bad compression method)”

4.2 下载 7Zip 的解压库

在 sourceforge 站点下载 sevenzipjbinding 压缩包。并且下载的也不是打包好的压缩文件





可是因为不支持最新的解压算法取消。

4.3 tomcat 下是否有调用外部 exe 的权限

4.4 启动tomcat失败

server可以正常启动项目,可是本地电脑不能启动。提示信息: "org.apache.catalina.LifecycleException: Failed to start component"





当本地 tomcat6 測试调用外部 exe 成功之后,就考虑在实际项目中測试项目是否成功,实际项目中用的是 tomcat7,同一时候包括了对应的 jdk 目录,进行了一定的改装。比方:改动了存放 webapp 的目录路径等;删除了一些不必要的文件等;





发现终于原因是由于: 启动时使用了本地较低版本号的 jdk,设置 JAVA_HOME 为打包自带的 jdk 目录就可以。

5 參考资料

1. runtime.getruntime.exec 中 waitfor 的使用方法



程序设计时,有时候须要在等待调用的系统程序完毕操作后,当前线程才干做下一步操作,此时能够用类Process的方法waitFor()来实现,它会堵塞当先线程直至调用程序执行结束。







2. 正确的调用系统命令——为Process.waitFor设置超时以及其它



所以在代码中增加超时控制是必须的。可是Process.waitFor()本身并不支持超时时间设置,

一个方法是改用非堵塞的Process.exitValue()方法,然后轮询检查进程状态,这样的方式比較消耗CPU,以至于轮询间隔也不能设置得太小,总归不是非常完美。

另外就是另起一个线程来调用程序,在主线程中发现超时的时候,直接调用process.destroy()终止进程。



3. When Runtime.exec() won't

介绍为什么不能正常运行 Runtime 函数






在 Java 项目中解压7Zip特殊压缩算法文件的更多相关文章

  1. 在Ubuntu系统中解压rar和zip文件的方法

    大家在以前的windows系统中会存有很多rar和zip格式的压缩文件,Ubuntu系统默认情况下对这些文件的支持不是很好,如果直接用"归档管理器"打开会提示错误,因此今天跟大家分 ...

  2. 在java项目中怎样利用Dom4j解析XML文件获取数据

    在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...

  3. linu中解压不同后缀的文件

    1.*.tar 用 tar –xvf 解压 2.*.gz 用 gzip -d或者gunzip 解压 3.*.tar.gz和*.tgz 用 tar –xzf 解压 4.*.bz2 用 bzip2 -d或 ...

  4. Linux中解压、压缩 ZIP文件

    解压 unzip -o -d /home/v-gazh myfile.zip # 把myfile.zip文件解压到 /home/v-gazh/ # -o:不提示的情况下覆盖文件: # -d:-d /h ...

  5. Java代码中解压RAR文件

    import java.io.File; import java.io.FileOutputStream; import de.innosystec.unrar.Archive; import de. ...

  6. java项目中读取src目录下的文件

    private void getUser(String tmpfile){ Properties props = new Properties(); props.load(DbTask.class.g ...

  7. ckeditor编辑器在java项目中配置

    一.基本使用: 1.所需文件架包 A. Ckeditor基本文件包,比如:ckeditor_3.6.2.zip 下载地址:http://ckeditor.com/download 2.配置使用 A.将 ...

  8. Ant在Java项目中的使用(一眼就看会)

    参考:http://www.cnblogs.com/zhengqiang/p/5557155.html Ant是跨平台的构建工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将A ...

  9. UCenter在JAVA项目中实现的单点登录应用实例

    Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...

随机推荐

  1. duck

    http://bjdw.artgooo.com/event/rubber/duck.shtml

  2. HDU3572_Task Schedule(网络流最大流)

    解题报告 题意: 工厂有m台机器,须要做n个任务.对于一个任务i.你须要花费一个机器Pi天,并且,開始做这个任务的时间要>=Si,完毕这个任务的时间<=Ei. 对于一个任务,仅仅能由一个机 ...

  3. 微软vs2015先行,Visual Studio 2015正式版离线iso及在线下载(附key)附带百度云盘地址

    win10正式版发布之前我们迎来了vs2015正式版,迫不及待要下载朋友可以看看 Visual Studio Community 2015简体中文版(社区版,针对个人免费): 在线安装exe:http ...

  4. How to retreive raw post data from HttpServletRequest in java

    public static String getPostData(HttpServletRequest req) { StringBuilder sb = new StringBuilder(); t ...

  5. Oracle Patch Bundle Update

    一.相关知识介绍 以前只知道有CPU(Critical Patch Update)和PSU(Patch Set Update),不知道还有个Bundle Patch,由于出现了TNS-12531的BU ...

  6. web端、android端的文件上传

    1.web端的文件上传. 这里是利用了第三方的jar包.这里所需要的jar包我已经上传到本博客的资源里了,以下是连接 http://download.csdn.net/detail/caihongsh ...

  7. UVA 6480 Zombie Invasion(模拟退火)

    A group of survivors has arrived by helicopter to an isolated island. The island is made up of a lon ...

  8. Android下QQ空间查看大图特效

    近期在做一个项目,里面有一个功能是实现Android QQ好友动态里面的缩略图放大,查看大图的效果.用过都知道,这个特效非常赞的,没用过的下载个玩玩吧.我刚開始以为放大的那个大图是一个Activity ...

  9. Swift - 字符串(String)用法详解

    下面对String常用的属性和方法做个总结 1,判断是否为空:isEmpty 1 2 3 var str:String if str.isEmpty{ } 2,获取字符数量:countElements ...

  10. EasyUI - 使用一般处理程序 HttpHandler (.ashx)

    以easyui中的panel中,使用url加载数据为列. 效果: html代码: <div id="p" style="padding: 10px;"&g ...