✅作者:TuNan
✨个人主页:图南的个人主页
😉欢迎关注🔎点赞😍收藏⭐留言💌
一、引言
- 我们编写好了一个java文件后使用命名行运行代码首先要通过输入javac ./Main.java执行编译转换为字节码文件:
- 然后通过java -cp . Main来运行我们的代码
这个类的作用就是通过我们的代码来执行命令并获取相关信息
二、概述
我们先来看看Process类在API中的解释:
Process提供对ProcessBuilder.start和Runtime.exec启动的本机进程的控制。 该类提供了从进程执行输入,执行输出到进程,等待进程完成,检查进程的退出状态以及销毁(杀死)进程的方法。 ProcessBuilder.start()和Runtime.exec方法创建本机进程并返回Process的子类实例,该实例可用于控制进程并获取有关它的信息。
默认情况下,创建的进程没有自己的终端或控制台。 其所有的标准I / O(即标准输入,标准输出,标准错误)操作将被重定向到父进程,在那里他们可以经由使用所述方法获得的流进行访问getOutputStream() , getInputStream() ,和getErrorStream() 。 父进程使用这些流将输入提供给进程并从进程输出。 由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取进程的输出流可能会导致进程阻塞甚至死锁。
下面是关于 Process 类的六个主要方法:
由于Process类是Object类的直接子类,所以除了Object的基础方法外,以上便是Process所有的全部方法。
三、详细说明
- 启动新进程:
- 可以使用 Runtime.getRuntime().exec(String command) 方法启动一个新的进程。这个方法将指定的命令作为字符串参数,并返回一个 Process 对象,该对象代表了新进程的执行。
- 还可以使用 ProcessBuilder 类来更灵活地配置和启动进程,可以设置工作目录、环境变量等。这样可以更精确地控制新进程的运行。
- 与进程交互:
- 一旦你有了一个 Process 对象,你可以使用它来与进程进行交互。你可以获取进程的输入流(标准输入)、输出流(标准输出)和错误流(标准错误),从中读取或写入数据。这样可以与进程进行双向通信。
- 你可以使用 getInputStream()、getOutputStream() 和 getErrorStream() 方法分别获取这些流。
- 使用这些流,你可以向进程发送输入,读取它的输出,以及处理错误信息。比如使用以下代码就能获取到程序的输出信息:
if (exitValue == 0) {
System.out.println("编译成功");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getInputStream()));
String compileInfo;
while ((compileInfo = bufferedReader.readLine()) != null) {
System.out.println(compileInfo);
}
} else {
System.out.println("编译失败" + exitValue);
}
注意:如果我们要获取控制台的输入要调用的是输出流而不是输入流
- 等待进程结束:
- 使用 waitFor() 方法可以让当前线程等待与 Process 对象相关联的进程执行完成。这可以用于确保在继续执行后续代码之前等待进程完成。 此方法会返回一个int值(错误码),如果为0则表示程序正常运行
- 获取进程的退出值:
- 使用 exitValue() 方法可以获取与 Process 对象相关联的进程的退出值。这个值通常是进程的返回代码,通常用于指示进程是否成功执行。
- 如果进程尚未完成,调用 exitValue() 方法将抛出一个异常。
- 销毁进程:
- 使用 destroy() 方法可以强制终止与 Process 对象相关联的进程。这应该谨慎使用,因为它可能导致进程异常终止,可能会导致数据丢失或不一致性。
四、进程工具类
@Data
public class ExecuteMessage {
/**
* 执行结果
*/
private Integer exitValue;
/**
* 执行信息
*/
private String message;
/**
* 错误信息
*/
private String errorMessage;
}
public class ProcessUtils {
public static ExecuteMessage runProcessAndGetMessage(Process runProcess, String opName) {
ExecuteMessage executeMessage = new ExecuteMessage();
try {
int exitValue = runProcess.waitFor();
executeMessage.setExitValue(exitValue);
if (exitValue == 0) {
System.out.println(opName + "成功");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
StringBuilder compileInfoBuilder = new StringBuilder();
// 逐行读取编译信息
String compileInfo;
while ((compileInfo = bufferedReader.readLine()) != null) {
compileInfoBuilder.append(compileInfo);
}
executeMessage.setMessage(compileInfoBuilder.toString());
} else {
System.out.println(opName + "失败" + exitValue);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
StringBuilder compileInfoBuilder = new StringBuilder();
// 逐行读取编译信息
String compileInfo;
while ((compileInfo = bufferedReader.readLine()) != null) {
compileInfoBuilder.append(compileInfo);
}
executeMessage.setMessage(compileInfoBuilder.toString());
BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
StringBuilder errorCompileInfoBuilder = new StringBuilder();
// 逐行读取编译信息
String errorCompileInfo;
while ((errorCompileInfo = errorBufferedReader.readLine()) != null) {
errorCompileInfoBuilder.append(errorCompileInfo);
}
executeMessage.setErrorMessage(errorCompileInfoBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return executeMessage;
}
}