本文共 2740 字,大约阅读时间需要 9 分钟。
Java中ProcessBuilder.start()和Runtime.exec()方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息。
Process类提供了从进程输入、输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
Java中创建的Process子进程没有自己的终端或控制台;它的所有标准IO重定向到父进程,父进程使用这些流来提供到子进程的输入和获得从子进程的输出:
因为平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流出现失败(或未读取),则可能导致子进程阻塞,甚至产生死锁。
当没有Process对象的更多引用时(在Java中离开作用域时),不是杀掉子进程,而是继续异步执行子进程。若要杀掉子进程,需通过destroy()函数来实现。Runtime.getRuntime()提供了多个重载方法以启动子进程:可接受一个单独的字符串(通过空格来分隔可执行命令程序和参数);也可以接受字符串数组参数。
命令行启动
通过windows的cmd /c
+要运行的命令可以方便的启动所需的程序。通过此命令也可以一次执行多条命令:
cmd /c cd c:/mypath && start mypro.exe
通过命令行执行启动程序时,程序启动完成后命令行会退出,所以Java中对应的Process也会完成退出。
public void runCommand(String strCmd){ // cmd /c cd c:\tmp && start test.ext String strRun = "cmd /c"; strRun += strCmd; try{ Process proc = Runtime.getRuntime().exec(strRun); if(!proc.waitFor(1, TimeUnit.SECONDS)){ System.out.println("Wait timeout!!!"); } } catch(Exception ex){ ex.printStackTrace(); }}
直接启动
明确知晓要运行的程序与对应参数的情况下,也可直接通过exec启动进程。此时,若进程通过stdout有输出,则需要通过getInputStream来读取(否则,若缓冲区满时,则子进程会被阻塞掉);若没有,则不需要处理。
public void runApp(String strExe, String strParam, String strPath) { Thread thr = new Thread(() -> { String strRun = Paths.get(strPath, strExe).toString(); strRun += " " + strParam; File fPath = new File(strPath); try { Process proc = Runtime.getRuntime().exec(strRun, null, fPath); InputStream inStream = proc.getInputStream(); try (InputStreamReader reader = new InputStreamReader(inStream); BufferedReader br = new BufferedReader(reader);) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } catch (Exception ex) { ex.printStackTrace(); } }); thr.start();}
ProcessBuilder实例管理一个进程属性集,ProcessBuilder的start()方法利用这些属性创建一个新的Process实例。start()方法可以从同一实例重复调用,以利用相同或者相关的属性创建新的子进程。
public void getIPv4Address() { ProcessBuilder pbGet = new ProcessBuilder("ipconfig", "/all"); try { Process process = pbGet.start(); try (InputStreamReader inReader = new InputStreamReader(process.getInputStream(), "GBK"); BufferedReader br = new BufferedReader(inReader);) { String line; while ((line = br.readLine()) != null) { if (line.indexOf("IPv4") != -1) { System.out.println(line); } } } } catch (IOException e) { e.printStackTrace(); }}
转载地址:http://pgnlf.baihongyu.com/