在 Java 项目中解压7Zip特殊压缩算法文件
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特殊压缩算法文件的更多相关文章
- 在Ubuntu系统中解压rar和zip文件的方法
大家在以前的windows系统中会存有很多rar和zip格式的压缩文件,Ubuntu系统默认情况下对这些文件的支持不是很好,如果直接用"归档管理器"打开会提示错误,因此今天跟大家分 ...
- 在java项目中怎样利用Dom4j解析XML文件获取数据
在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...
- linu中解压不同后缀的文件
1.*.tar 用 tar –xvf 解压 2.*.gz 用 gzip -d或者gunzip 解压 3.*.tar.gz和*.tgz 用 tar –xzf 解压 4.*.bz2 用 bzip2 -d或 ...
- Linux中解压、压缩 ZIP文件
解压 unzip -o -d /home/v-gazh myfile.zip # 把myfile.zip文件解压到 /home/v-gazh/ # -o:不提示的情况下覆盖文件: # -d:-d /h ...
- Java代码中解压RAR文件
import java.io.File; import java.io.FileOutputStream; import de.innosystec.unrar.Archive; import de. ...
- java项目中读取src目录下的文件
private void getUser(String tmpfile){ Properties props = new Properties(); props.load(DbTask.class.g ...
- ckeditor编辑器在java项目中配置
一.基本使用: 1.所需文件架包 A. Ckeditor基本文件包,比如:ckeditor_3.6.2.zip 下载地址:http://ckeditor.com/download 2.配置使用 A.将 ...
- Ant在Java项目中的使用(一眼就看会)
参考:http://www.cnblogs.com/zhengqiang/p/5557155.html Ant是跨平台的构建工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将A ...
- UCenter在JAVA项目中实现的单点登录应用实例
Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...
随机推荐
- vi/vim高级命令集粹
vi/vim高级命令集粹 (ctrl +v过来 留着以后看) 1.交换两个字符位置 xp 2.上下两行调换 ddp 3.把文件内容反转 :g/^/m0/ (未通过) 4.上下两行合并 J 5.删除所有 ...
- 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
查找并指定符号文件和源文件:指定符号加载行为.使用符号和源服务器上:加载符号自动或在要求. 内容 查找符号 (.pdb) 文件 查找源文件 查找符号 (.pdb) 文件 说明 在之前的 Vis ...
- 如何安装(装载)axure组件(部件)
我们在网络上经常可以下载到很多网友精心设计的axure组件,这些组件给我们节省了很多的时间,方便了我们进行原型设计,可是对于很多刚刚接触axure的朋友就遇到了2个问题: 第一:到哪里去下载这些组件 ...
- 一起talk GDB吧(第六回:GDB改动程序执行环境)
各位看官们,大家好,上一回中我们说的是GDB查看信息的功能,而且说了怎样使用GDB查看程序执行时的 信息.这一回中,我们继续介绍GDB的调试功能:改动程序执行环境.当然了,我们也会介绍怎样使用GDB ...
- C++学习之路—多态性与虚函数(二)纯虚函数与抽象类
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1 纯虚函数 在前面的博客中已经提到:有时 ...
- Swift中使用typealias定义一个闭包closure
在OC中我们定义一个Blocks是这样定义的: typedef void (^ZWProgressHUDCompletionBlock)(); 在Swift中定义一个闭包是这种: typealias ...
- php与文件操作
一.目录操作 首先是从目录读取的函数,opendir(),readdir(),closedir(),使用的时候是先打开文件句柄,而后迭代列出: <?php $base_dir="fil ...
- vc中改变对话框的背景色
---- 笔者曾在<软件报>2000年第5期中讨论过如何改变控件的颜色,但还有相当一部分的读者来信提问:一个基于对话框的MFC AppWizard应用程序中,如何改变对话框的背景颜色呢?对 ...
- C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)
先说实在的:最终解决办法是实现IDocHostUIHandler接口,在GetHostInfo方法里解决,但“实现接口”意味着QueryInterface.AddRef.Release三个方法必须实现 ...
- SVN权限解析规则详解(转)
首先创建一个版本库后,会生成最初的目录结构和基本的配置文件,本文主要分析“authz”文件的内容:我们先抛开alias和groups不谈,将重点放在路径的权限配置上. 一. 权限格式 svn权限的基本 ...