我正在尝试在Windows Server 2003计算机上获取正在运行的进程及其文件路径的列表。我正在使用以下代码尝试这样做:
protected Map<String,String> getProcesses() {
Map<String,String> processes = new HashMap<String,String>();
try {
String line;
Process p = null;
// Windows
if (OS.indexOf("win") >= 0) {
p = Runtime.getRuntime().exec("wmic process get description,executablepath");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
LOG.info("Entering while loop");
while ((line = input.readLine()) != null) {
LOG.info("blah");
String[] array = line.split("\\s+");
if (array.length > 1) {
processes.put(array[0], array[1]);
}
}
LOG.info("Exited while loop");
input.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return processes;
}
程序在while条件下陷入无限循环。 “blah”和“退出while循环”从不输出到日志。我在win7本地机器和服务器上的命令提示符下运行命令,输出信息就好了。我也在我的本地机器上运行了上面的代码也工作正常。看起来Java和Windows Server 2003之间的一些问题是我在过去3小时的谷歌搜索中找不到的。任何帮助将不胜感激。
答案 0 :(得分:9)
在获取和使用OutputStream
之前,您需要获取并关闭InputStream
。这将确认您已经开始完成向流程发送输入(在这种情况下,没有输入)的过程。
p.getOutputStream().close();
请记住,在Process
对象上,getInputStream()
输入来自进程的输出流,getOutputStream()
输出将转到进程的输入流。
答案 1 :(得分:2)
请记住,如果未达到输入结束,BufferedReader.readLine()
操作将会阻止,请参阅here。
我认为Process
{{1}}中解释了您遇到的问题:
创建进程的方法可能不适用于某些本机平台上的特殊进程,例如本机窗口进程,守护程序进程,Microsoft Windows上的Win16 / DOS进程或shell脚本。创建的子进程没有自己的终端或控制台。其所有标准io(即stdin,stdout,stderr)操作将通过三个流(getOutputStream(),getInputStream(),getErrorStream())重定向到父进程。父进程使用这些流向子进程提供输入并从子进程获取输出。由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。