我正在尝试使用processbuilder从Java调用cmd命令。但是我面临的问题很少。
当我使用使用Arrays.asList构建的List时,应用程序在执行br.readline()后无限地挂起(不是因为循环而是在readLine方法)。使用String数组给出输出。我检查了grepcode,它看起来应该没有任何问题,因为当从processbuilder调用start方法时,它们都会被转换回数组。 (链接:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/lang/ProcessBuilder.java#ProcessBuilder)。我不确定是什么导致了这种异常现象。
此程序有时无法提供正确的输出。如果我使用process.destroy()方法并获取exitValue,则显示1.如果我注释掉process.destroy()方法,那么异常将导致该进程未退出。我想这可能是线程竞争条件。但是,process.waitFor()没有效果。它有时仍会产生错误的输出。我们如何测试这些情况并找出问题的真正原因?
我需要在cmd中调用一些命令。但是,数组元素充当前一个的参数。例如,如果我使用elemets制作数组cmd / C dir whoami。然后这会产生错误的输出,因为whoami充当dir的参数。什么是向cmd独立提供命令的正确方法?
以下是具有相同问题的示例代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Sample {
public static void main(String[] args) throws Exception {
//List<String> commandList = Arrays.asList("cmd.exe","dir");
String[] commandList = {"cmd.exe", "/C", "dir"};
//String[] commandList = {"cmd.exe", "/C", "dir", "whoami"};
//String[] commandList = new String[] {"cmd.exe", "/C", "dir"};
ProcessBuilder processBuilder = new ProcessBuilder(commandList);
Process process = processBuilder.start();
//process.waitFor();
BufferedReader iReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String tempStr= "";
StringBuffer buffer = new StringBuffer();
while((tempStr = iReader.readLine())!=null){
buffer.append(tempStr+System.lineSeparator());
}
System.out.println(buffer.toString());
process.destroy();
int exitValue = process.exitValue();
System.out.println(exitValue);
}
}
答案 0 :(得分:2)
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
解决这个问题(一般来说这是一个好主意,除非您打算以其他方式读取错误流)。process.waitFor()
。 在读完所有输出之前,不要调用process.waitFor(); waitFor()等待进程结束,并且您无法读取不再运行的进程的输出。&&
链接命令;例如:new ProcessBuilder("cmd.exe", "/C", "dir && date /t")
。如果这不起作用,您可以尝试创建临时.bat文件并将其传递给cmd / c。如果这是不可接受的,您可能必须为要运行的每个命令创建一个单独的进程。顺便说一句,StringBuffer已经过时了。请改用StringBuilder,因为它没有不必要的同步开销。