Java 使用Runtime.getRuntime.exec 和 ProcessBuilder 调用外部命令

这几天在做来到公司以来的第一个项目,一个可以生成statcvs report的web小工具

昨天一天纠结于调用外部命令后程序阻塞的问题,直到刚刚终于解决。

我要调用的外部指令是 cvs log 生成某个项目源码的cvs日志文件

一开始我用的是Runtime.getRuntime.exec(cmd)方法,

Process process = Runtime.getRuntime().exec("cmd");

OutputStream os = process.getOutputStream();

InputStream es = process.getErrorStream();

runCommand(os,"cd " + projectPath + "\n");

runCommand(os, "E:" + "\n");

runCommand(os, "cvs log -d \"" + date1 + "<" + date2 + "\" > " + logFilePath + "\n");


但是使用这个方法调用指令总是会运行一会儿就阻塞住。

后来我又改用ProcessBuilder, 同样出现了阻塞的问题,我google了一下,发现问题在于:

都有自己的标准输入、标准输出、标准错误输出,对于某些 依赖于OS的进程,可能其输出缓冲区很小,如果不能及时的读出(标准输出、标注错误输出),将导致进程不能正常退出。

我的程序中有对标准输出做了处理,但是cvs log指令还有错误输出,于是我在处理标准输出前新建一个线程读取错误输出缓冲区:

Process process = builder.start();

			InputStream is = process.getInputStream();
			InputStream es = process.getErrorStream();
			
			ErrorOutputReader errReader = new ErrorOutputReader(es);
			
			errReader.start();
			
			byte[] re=new byte[128];

			while (is.read(re)!=-1) {

				String temp = new String(re, 0, len(re),"UTF-8");

				System.out.println(temp);

				result = result+ temp;

			}
这样之后程序正常结束了,但让人恼火的是ProcessBuilder 不支持输出重定向指令,而我用上面的方法,即读取字节码再转为string存入文件生成的log文件却不准确,导致statcvs无法解析。


绝望之际我又转投支持重定向指令Runtime.getRuntime.exec(cmd),它能够准确生成log文件,而且也不用去care 标准输出的问题,我只要将错误输出缓冲区读完就行,

但是奇怪的是程序依旧阻塞,我百思不得其解,  纠结了一天始终卡在那里, 我想我脑袋都阻塞了。

后来我想 难道是标准输入的问题, 于是我加入了一句process.getOutoutStream().close(), 居然就神奇地不阻塞了。


这是什么原因?  莫非这个close()功能类似于命令行里输入ctrl+z?


总之问题就这样解决了。  好交差去喽!!!







Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值