Java记录——执行系统命令

概述

Java执行系统命令,典型的方式,通过以下两个类来实现

  • Runtime
  • ProcessBulider

Runtime

  • Runtime是一个单例的实例
  • Runtime运行应用程序与运行应用程序的环境进行交互
  • Runtime是Java运行时环境,应用程序不能创建属于自己的实例,需要通过getRuntime()方法获取
  • 代码实例
private Process exec(String command) throws IOException {
	Runtime runtime = Runtime.getRuntime();
	Process process = runtime.exec(command);
    return process;
}

ProcessBulider

  • ProcessBulider用来创建操作系统进程
  • 使用start方法,可以重复创建新的子进程
  • 代码实例
private Process start(String command) throws IOException { 
	//将一整条命令转成String数组
	StringTokenizer st = new StringTokenizer(command);
    String[] cmdarray = new String[st.countTokens()];
    for (int i = 0; st.hasMoreTokens(); i++) {
		cmdarray[i] = st.nextToken();
    }
    ProcessBuilder builder = new ProcessBuilder(cmdarray);
	Process process = builder.start();
	return process;
}

Runtime与ProcessBuilder实现执行系统命令的区别

  • 本质两种方式并没有什么区别,Runtime.getRuntime().exec(command)方法内部也是调用new ProcessBuilder().command(command).start()方法
  • Runtime的exec方法
public Process exec(String[] cmdarray, String[] envp, File dir)throws IOException {
	return new ProcessBuilder(cmdarray)
				.environment(envp)
				.directory(dir)
				.start();
}

Process

  • 通过ProcessBuilder#start()Runtime#exec()创建一个进程,同时返回一个Process实例
  • Process实例可以控制该进程和获取进程信息,如输出的错误日志等
  • 方法
    • getOutputStream
    • getInputStream
    • getErrorStream
      • 获取命令执行中的错误日志
    • waitFor
      • 当前进程进入等待状态,直到该进程结束或退出
    • waitFor(long,TimeUnit)
    • exitValue
    • destroy
      • 终止该进程
    • destroyForcibly
    • isAlive

问题记录

  1. 子进程(Process)的输出和错误信息过多时会导致进程阻塞住,执行不下去
    • 主动取出输出和错误日志
public static void main(String[] args) throws IOException {
	String command="Ping 192.168.1.16";
	Process start = start(command);
	InputStream is = start.getInputStream();
	BufferedReader br = new BufferedReader(new InputStreamReader(is,Charset.forName("gbk")));
	String message;
	while((message=br.readLine())!=null){
		System.out.println(message);
	}
	InputStream errorStream = start.getErrorStream();
	while(errorStream.read()!=-1){}
}
  • 但是当遇到像ffmpeg的拉流推流命令,这种会不停的输出日志信息的情况,使用以上方式将信息不断取出,也是不合适的,最好就是控制日志的输出

猜你喜欢

转载自blog.csdn.net/changye1/article/details/82720669