Java执行操作系统命令-Process抽象类(1)
Java 8
Windows 10
Eclipse Version: 2022-09 (4.25.0)
--
序章
测试使用Java程序执行操作系统命令。ben发布于博客园
需要用到 抽象类Process:
// @since JDK1.0
public abstract class Process {
//...
}
在类注释中,提到了 ProcessBuilder、Runtime 两个类,用来生成Process对象——执行命令。ben发布于博客园
注,本文仅涉及Windows上的命令执行。
注,本文只测试执行Windows命令 cd、dir 两个命令。ben发布于博客园
测试目录:D:\javaprocess
涉及类:
java.lang.Process
java.lang.ProcessBuilder
java.lang.Runtime
执行命令:使用ProcessBuilder类
ProcessBuilder类 结构:ben发布于博客园
测试代码:输出执行后的 InputStream、ErrorStream 的内容。
/**
* 测试:ProcessBuilder
*/
public static void test1(String... cmd) {
cs.accept("start test1..");
try {
Process ps = new ProcessBuilder()
.command(cmd)
.start();
cs.accept("1、InputStream:");
processIs(ps.getInputStream());
cs.accept("2、ErrorStream:");
processIs(ps.getErrorStream());
cs.accept("3、----END----");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 输出InputStream的内容:字符集 GB2312
* @param is
* @throws IOException
*/
private static void processIs(InputStream is) throws IOException {
final int size = 1024;
byte[] buffer = new byte[size];
Charset cset = Charset.forName("GB2312");
cs.accept("cset=" + cset);
StringBuffer sb = new StringBuffer();
int ret = 0;
int total = 0;
while ((ret = is.read(buffer, 0, size)) > 0) {
total += ret;
String chunk = new String(buffer, 0, ret, cset);
sb.append(chunk);
}
cs.accept("ret=" + ret + ", total=" + total);
cs.accept("sb=" + sb.length() + ", content=" + sb);
is.close();
}
测试存在的目录
执行:test1("cmd", "/C", "dir", "d:\\javaprocess");ben发布于博客园
注意,这里的 cmd、/C 是必须的(Windows中)。
测试结果:目录存在,正常输出。
目录存在,执行正常,InputStream有数据,而ErrorStream没有数据。ben发布于博客园
测试不存在的目录
执行:test1("cmd", "/C", "dir", "d:\\javaprocessnull");ben发布于博客园
测试结果:目录不存,ErrorInput也要数据输出——找不到文件。
问题:这里的 InputStream 也有数据,是否可以将两者合并呢?ben发布于博客园
回答:可以。在start()之前执行 redirectErrorStream(true) 即可。
问题:测试时传入了4个参数,可以合并为一个吗?ben发布于博客园
回答:不可以。
执行 test1("cmd /C dir d:\\javaprocess");
测试结果:CreateProcess error=2, 系统找不到指定的文件。ben发布于博客园
执行命令:使用Runtime类
Runtime类 结构:
执行命令会用到其中的 exec函数,可以看到 exec函数有多个函数签名。
// 字符串的命令
public Process exec(String command) throws IOException {}
public Process exec(String command, String[] envp) throws IOException {}
public Process exec(String command, String[] envp, File dir) throws IOException {}
// 字符数组的命令
public Process exec(String cmdarray[]) throws IOException {}
public Process exec(String[] cmdarray, String[] envp) throws IOException {}
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException {}
测试代码:test2(String cmd)
/**
* 测试:Runtime.getRuntime().exec(...)
*/
public static void test2(String cmd) {
cs.accept("start test2..cmd=" + cmd);
try {
Process ps = Runtime.getRuntime().exec(cmd);
cs.accept("1、InputStream:");
processIs(ps.getInputStream());
cs.accept("2、ErrorStream:");
processIs(ps.getErrorStream());
cs.accept("3、----END----");
} catch (IOException e) {
e.printStackTrace();
}
}
注,会使用前面的 processIs(InputStream is) 函数。
测试存在的目录
执行:test2("cmd /C dir d:\\javaprocess");
测试结果:
注意,这里的命令是一个字符串。
测试不存在的目录
执行:test2("cmd /C dir d:\\javaprocessnull");
测试结果:
多条命令执行:Runtime类
场景:进入一个目录,再输出目录下的内容。
执行下面的语句可以实现吗?
test2("cmd /C cd d:\\javaprocess");
test2("cmd /C dir .");
回答:不可以。
两个Process是不同的进程——即不同的JVM。
执行多条命令,在使用Runtime类时,可以使用 && 符号。
执行:test2("cmd /C cd d:\\javaprocess && dir"); 或者 test2("cmd /C cd d:\\javaprocess && dir .");
测试结果:
问题:ProcessBuilder类 怎么执行多条命令呢?TODO
参考资料
1、java Process 执行批命令 cmd
by 老谭TYH
于 2022-11-22 12:18:50 发布
原文链接:https://blog.csdn.net/qq_30436011/article/details/127979994
2、
ben发布于博客园