1、Runtime类的使用
Runtime 类主要描述的是应用程序运行的环境
每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
Runtime run = Runtime.getRuntime(); //获取应用运行环境的对象
exit() //推出虚拟机
long freeMemory() //获取可以内存数
gc() //调用垃圾回收器程序,但是调用该方法的时候不会马上就运行gc
long maxMemory() //获取jvm最大内存容量
long totalMemory() //获取总内存
Process exec(String command) //启动一个字符串命令的进程(根据指定的路径执行对应的可执行文件)
exec(String[] cmdArray) //调用外部程序,入参cmdArray的元素将组合成为一条完整的外部可执行程序的启动路径或命令。
exec(String command, String[] envp) //在调用外部程序之前设置系统环境变量,该变量仅供command入参使用,envp每个元素为一个系统环境变量,并且字符串格式为“环境变量名=环境变量值”。
exec(String command, String[] envp, File dir) //除了设置系统环境变量外,还通过入参dir设置当前工作目录。
exec("cmd /c dir > %dest%", new String[]{"dest=c:\\dir.txt", new File("d:\\test")})
- cmd /c dir 是执行完dir命令后关闭命令窗口。
- cmd /k dir 是执行完dir命令后不关闭命令窗口。
- cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。
- cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。
**exec("cmd /c set CLASSPATH=D:\\ && javac D:\\a.java && java a");**
一个“&&”完美搞定~~
实测连接三条命令没问题
用Runtime类的exec()方法传入一个命令(exec()方法有几个重载的方法,可以自己学习),创建一个子进程,结果返货一个Process类的实例,通过这个实例我们可以管理创建的子进程。
JavaSE5之前使用Runtime的exec方法执行本地命令.在JavaSE5之后,可以使用ProcessBuilder执行本地命令.
2、Process类的使用
构造Process对象:
- 第一为使用java.lang.Runtime提供的方法exec(String command),使用它的作用与直接在linux shell或windows cmd下直接输入command作用一致,它会返回一个Process的实例;
- 第二是使用ProcessBuilder类的start()方法,即可返回一个Process实例。(需要注意的是,ProcessBuilder的构造函数接受的参数列表为可变参数列表,在java中声明语法为void function(type… vars))这里的Process已经是一个正在运行的进程了。
estroy() //杀掉子进程。
exitValue() //返回子进程的出口值。
InputStream getErrorStream() //获得子进程的错误流。
InputStream getInputStream() //获得子进程的输入流。
OutputStream getOutputStream() //获得子进程的输出流。
waitFor() //导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止。
3、ProcessBuilder
ProcessBuilder(List<String> command) //利用指定的操作系统程序和参数构造一个进程生成器。
ProcessBuilder(String... command) //利用指定的操作系统程序和参数构造一个进程生成器。
List<String> command() //返回此进程生成器的操作系统程序和参数。
ProcessBuilder command(List<String> command) //设置此进程生成器的操作系统程序和参数。
ProcessBuilder command(String... command) //设置此进程生成器的操作系统程序和参数。
File directory() //返回此进程生成器的工作目录。
ProcessBuilder directory(File directory) //设置此进程生成器的工作目录。
Map<String,String> environment() //返回此进程生成器环境的字符串映射视图。
boolean redirectErrorStream() //通知进程生成器是否合并标准错误和标准输出。
ProcessBuilder redirectErrorStream(boolean redirectErrorStream) //设置此进程生成器的 redirectErrorStream 属性。
Process start() //使用此进程生成器的属性启动一个新进程。
tips:
- 多行命令时(即多个parmlist),每个parmlist行命令都是需要去创建一个进程运行;
- 跟dos命令的不同点是,在dos命令中可以敲一行命令带有多个参数,在这里,转换技巧是dos命令中但凡有一个空格,那么在processbuilder中就需要再增加一个parmList。
- 在需要调用cmd时,需在后面加 /c命令,如果没有该命令则会出现console控制台光标持续闪烁的问题。
实例:
@Test
public void testFFmpeg() {
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
List<String> command = new ArrayList<>();
command.add("D:/program/ffmpeg-20191229-e20c6d9-win64-static/bin/ffmpeg.exe");
command.add("-i");
command.add("D:/test/video/1.avi");
command.add("-y");//覆盖输出文件
command.add("-c:v");
command.add("libx264");
command.add("-s");
command.add("1280x720");
command.add("-pix_fmt");
command.add("yuv420p");
command.add("-b:a");
command.add("63k");
command.add("-b:v");
command.add("753k");
command.add("-r");
command.add("18");
command.add("D:/test/video/1.mp4");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len = inputStreamReader.read(c)) != -1) {
String s = new String(c, 0, len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}