Java借助Runtime调用外部程序阻塞的代码

有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf、ffmpeg来转换视频等。如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果:

InputStream stderr = process.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr, "GBK");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
    System.out.println(line);
int exitValue = process.waitFor();

对于一般的外部程序使用上面的阻塞代码就可以,至少pdf2swf.exe是没有问题的。

但我发现对于ffmpeg来说,以上代码会让程序卡住不动,需要使用另一种方式,封装成了一个方法,如下:

     @SuppressWarnings("static-access")
	public static int doWaitFor(Process process) {
		InputStream in = null;
		InputStream err = null;
		int exitValue = -1; // returned to caller when p is finished
		try {
			in = process.getInputStream();
			err = process.getErrorStream();
			boolean finished = false; // Set to true when p is finished
			while (!finished) {
				try {
					while (in.available() > 0) {
						// Print the output of our system call
						Character c = new Character((char) in.read());
						System.out.print(c);
					}
					while (err.available() > 0) {
						// Print the output of our system call
						Character c = new Character((char) err.read());
						System.out.print(c);
					}
					// Ask the process for its exitValue. If the process
					// is not finished, an IllegalThreadStateException
					// is thrown. If it is finished, we fall through and
					// the variable finished is set to true.
					exitValue = process.exitValue();
					finished = true;
				} catch (IllegalThreadStateException e) {
					// Process is not finished yet;
					// Sleep a little to save on CPU cycles
					Thread.currentThread().sleep(500);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (err != null) {
				try {
					err.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return exitValue;
	}

  

时间: 2024-10-14 12:11:23

Java借助Runtime调用外部程序阻塞的代码的相关文章

java使用RunTime调用windows命令行

当Java需要调用windows系统进行交互时,可以使用Runtime进行操作. 例子: 1.调用window中获取关于java相关的进行信息 Runtime rt = Runtime.getRuntime(); Process p = rt.exec("wmic process where caption=\"javaw.exe\" get caption,commandline /value"); BufferedReader br = new Buffered

Java中RunTime类介绍

Runtime 类代表着Java程序的运行时环境,每个Java程序都有一个Runtime实例,该类会被自动创建,我们可以通过Runtime.getRuntime() 方法来获取当前程序的Runtime实例. 获取当前Jvm的内存信息 /* * 获取当前jvm的内存信息,返回的值是 字节为单位 * */ public static void getFreeMemory() { //获取可用内存 long value = Runtime.getRuntime().freeMemory(); Syst

在Java中直接调用js代码(转载)

http://blog.csdn.net/xzyxuanyuan/article/details/8062887 JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Java中直接调用js代码 不能调用浏览器中定义的js函数,会抛出异常提示ReferenceError: “alert” is not defined.   package com.sinaapp.manjushri;  import javax.script.ScriptEngine;  import

java通过JNI调用c++代码

java通过JNI调用c++代码 1 用java约定接口,生成头文件 创建JniHelloWorld.java public class JniHelloWorld { public JniHelloWorld(){ } public native void sayHello(String name); } 生成头文件供c++使用 javah-jni JniHelloWorld 产生JniHelloWorld.h文件,里面是用c++代码规定了接口形式. 2生成动态链接库文件(http://blo

oracle使用java source调用外部程序

oracle使用java source调用外部程序

java实现调用Mysql存储过程分析代码

数据库的测试代码如下 : 1.新建表test,sql代码如下: create table test( field1 int not null ) TYPE=MyISAM ; insert into test(field1) values(1); 2.删除已存在的存储过程,代码如下: delimiter // -- 定义结束符号 drop procedure p_test; 3.mysql存储过程定义,代码如下: create procedure p_test() begin declare te

C#winform调用外部程序,等待外部程序执行完毕才执行下面代码

1.简单调用外部程序文件(exe文件,批处理等),只需下面一行代码即可 System.Diagnostics.Process.Start(“应用程序文件全路径”); 2.如果要等待调用外部程序执行完毕才执行下面代码,只需要在后面加上WaitForExit()方法 System.Diagnostics.Process.Start(应用程序文件全路径).WaitForExit(); 3.另一种方法:使用实例化方法不使用静态方法 1 Process process = new Process(); 2

[转]Java中Runtime.exec的一些事

0 预备知识 1 不正确的调用exitValue 2不正确的调用waitFor 3 一种可接受的调用方式 4 调用认为是可执行程序的时候容易发生的错误 5 window执行的良好示例 6 不良好的重定向命令输出 7 良好的重定向输出示例 8 总结 9 问答 0 预备知识 Runtime类是一个与JVM运行时环境有关的Singleton类,有以下几个值得注意的地方: 0.1 Runtime.getRuntime()可以取得当前JVM的运行时环境,这也是在Java中唯一得到运行时环境的方法. 0.2

深入研究java.lang.Runtime类

深入研究java.lang.Runtime类 一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用.      一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为.