在 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! ...
随机推荐
- Cocos2dx3.1 获取当前系统时间
以下是获代替码 原文地址:http://blog.csdn.net/qqmcy/article/details/28233565 // // Tools.h // // // Created by 杜 ...
- 重操JS旧业第六弹:基本类型包装
在前面已经知道js中的类型有boolean,string,number,undefined,function,object,其中boolean,number,string为值类型.所谓的基本类型包装, ...
- 更快地从IplImage转换成QImage
转:http://blog.sina.com.cn/s/blog_5c70dfc80100qzif.html 在Qt平台上使用OpenCV肯定会遇到从IplImage到QImage的转换问题,找了很多 ...
- Customize Spring @RequestParam Deserialization for Maps and/or Nested Objects
@RestController class MyController { @RequestMapping(...) public void test(Container container) { .. ...
- cocos2d-x游戏开发(十五)游戏加载动画loading界面
个人原创,欢迎转载:http://blog.csdn.net/dawn_moon/article/details/11478885 这个资源加载的loading界面demo是在玩客网做逆转三国的时候随 ...
- crm使用FetchXml聚合查询
/* 创建者:菜刀居士的博客 * 创建日期:2014年07月08号 */ namespace Net.CRM.FetchXml { using System; using Micr ...
- Appium Server 传递iOS参数
Appium server iOS Capabilities 参数 iOS Only Capability Description Values calendarFormat (Sim-only) ...
- linux:sed高级命令之n、N(转)
sed的语法格式: sed [option] {sed-command} {input-file} sed在正常情况下,将处理的行读入模式空间(pattern space),脚本中的“sed-comm ...
- XP教育网用户免费上网
本文针对 XP 教育网用户免费上网,其他系统未作测试.若有疑问百度空间留言 http://hi.baidu.com/itas109 http://blog.csdn.net/itas109 步骤 ...
- cocos2d-x学习日志(10) --射击游戏(喵星战争)
转载请标明:转载自[小枫栏目],博文链接:http://blog.csdn.net/rexuefengye/article/details/10553487 一.纵版射击游戏的特点 纵版射击游戏是一种 ...