2

我正在尝试获取 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”和“Exited while loop”永远不会输出到日志中。我已经在我的 win7 本地计算机和输出信息的服务器上的命令提示符下运行了该命令。我还在我的本地机器上运行了上面的代码,它也可以正常工作。看起来这是 Java 和 Windows Server 2003 之间的一些问题,我在过去 3 小时的谷歌搜索中无法找到。任何帮助将非常感激。

4

2 回答 2

10

OutputStream在获取和使用您的InputStream. 这将确认您已启动的流程已完成向流程发送输入(在本例中为无输入)。

p.getOutputStream().close();

请记住,在Process对象上,getInputStream()输入来自进程的输出流,而getOutputStream()输出则进入进程的输入流。

于 2012-11-13T19:49:22.967 回答
2

请记住,BufferedReader.readLine()如果没有到达输入的结尾,操作将阻塞,请参见此处

我认为您所遇到的情况在API中进行了解释Process

创建进程的方法可能不适用于某些本机平台上的特殊进程,例如本机窗口进程、守护进程、Microsoft Windows 上的 Win16/DOS 进程或 shell 脚本。创建的子进程没有自己的终端或控制台。它所有的标准io(即stdin、stdout、stderr)操作都会通过三个流(getOutputStream()、getInputStream()、getErrorStream())重定向到父进程。父进程使用这些流向子进程提供输入并从子进程获取输出。由于部分原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。

于 2012-11-13T19:53:46.190 回答