前言:最近做了一个Java跨平台开启,关闭,重启nginx的功能,在Java操作exe上遇到了一些问题,下面是对这个问题一个总结
一、Java操作exe的三种方式
(1)Runtime.getRuntime
Process proc = Runtime.getRuntime().exec("java");
/*** cmd方式
*@paramcommand 要执行的命令*/
private static voidtest1() {
BufferedReader bufferedReader= null;try{
String command= "cmd /c start nginx";//要执行的命令
String path = "D:/workspace-mars-2019-app/ywpt/nginx/windows";//打开文件的位置
File exeFile= newFile(path);
String[] str= new String[] {};//参数//执行命令返回执行的子进程对象//Process proc = Runtime.getRuntime().exec(command,str,exeFile);
Process proc = Runtime.getRuntime().exec("C:/Program Files (x86)/Notepad++/notepad++.exe");//获取子进程的错误流,并打印
bufferedReader = new BufferedReader(newInputStreamReader(proc.getErrorStream()));
String line= null;while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}catch(Exception ex) {
ex.printStackTrace();
}finally{if (bufferedReader != null) {try{
bufferedReader.close();
}catch(Exception ex) {
}
}
}
}
(2)ProcessBuilder
Process proc =new ProcessBuilder("java").start();
/*** ProcessBuilder调用cmd*/
private static voidtest2() {
BufferedReader bufferedReader= null;try{//执行命令返回执行的子进程对象
Process proc = new ProcessBuilder("C:/Program Files (x86)/Notepad++/notepad++.exe").start();//获取子进程的错误流,并打印
bufferedReader = new BufferedReader(newInputStreamReader(proc.getErrorStream()));
String line= null;while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}catch(Exception ex) {
ex.printStackTrace();
}finally{if (bufferedReader != null) {try{
bufferedReader.close();
}catch(Exception ex) {
}
}
}
}
/*** ProcessBuilder打开nginx
*@throwsIOException*/
private static voidtest7() {
BufferedReader bufferedReader= null;
ProcessBuilder pb= new ProcessBuilder("cmd ", "/c", "start nginx");
Map env =pb.environment();
pb.directory(new File("D:/workspace-mars-2019-app/ywpt/nginx/windows"));try{
Process proc=pb.start();//获取子进程的错误流,并打印
bufferedReader = new BufferedReader(newInputStreamReader(proc.getErrorStream()));
String line= null;while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}catch(Exception ex) {
ex.printStackTrace();
}finally{if (bufferedReader != null) {try{
bufferedReader.close();
}catch(Exception ex) {
}
}
}
}
(3)Desktop
Desktop.getDesktop().open(new File("D:/workspace-mars-2019-app/ywpt/nginx/windows/nginx.exe"));
/*** getDesktop方式
*
*@throwsIOException*/
private static void test3() throwsIOException {
BufferedReader bufferedReader= null;try{
Desktop.getDesktop().open(new File("C:/Program Files (x86)/Notepad++/notepad++.exe"));
}catch(Exception ex) {
ex.printStackTrace();
}finally{if (bufferedReader != null) {try{
bufferedReader.close();
}catch(Exception ex) {
}
}
}
}
二、Process的使用
(1)简介:
Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序)。
Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获取相关信息。
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。
(2)主要方法
InputStream getErrorStream() 获得子进程的错误流。
InputStream getInputStream() 获得子进程的输入流。
OutputStream getOutputStream() 获得子进程的输出流。
三、扩展
(1)Desktop打开指定文件
/*** 打开指定文件
*@throwsIOException*/
private static void test5() throwsIOException {
File file=new File("e://error.log");
java.awt.Desktop.getDesktop().open(file);
}
(2)Desktop打开指定文件夹
/*** 打开指定文件夹
*@throwsIOException*/
private static void test6() throwsIOException {
File file=new File("e://error.log");
java.awt.Desktop.getDesktop().open(file.getParentFile());
}
(3)Desktop打开指定文件
/*** 打开指定文件
*@throwsIOException*/
private static void test5() throwsIOException {
File file=new File("e://error.log");
java.awt.Desktop.getDesktop().open(file);
}