0

这是我的工作流程:

我从 DB 获得工作,我运行了一些任务,我运行了一个读取文件并生成另一个文件的外部程序(这通常需要不到 10 秒)。这是代码:

Process p = Runtime.getRuntime().exec(prog, null, new File(path));

BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

String s;
String errorString = "";
while((s = stdInput.readLine()) != null) {
    if(s.toLowerCase().contains("error")) {
        Log.writeLog("error: " + s);
        errorString += s + "\r\n";
    }
}

if(errorString.length() > 1) {
    Emailer.email(name + "*" + errorString, "ERROR");
}

while((s = stdError.readLine()) != null) {
    Log.writeLog("ERROR: " + s);
}

但是,该片段挂起。我通过 LogMeIn 控制运行代码的服务器,一旦我登录,进程就会畅通无阻(总运行时间约为 280 秒)并继续。该过程没有产生ERROR结果。这种情况不时发生,比我们想的要频繁。我们在程序中做了相当多的小型 IO 操作,硬盘有时会变得很满。

知道会发生什么吗?

谢谢!

编辑:服务器只是一台连接到 LogMeIn 的普通计算机。我担心的是,由于它是一台普通计算机,它可能会在不使用时关闭 CPU/硬盘驱动器(不确定术语是否正确)。这可以在一定程度上解释为什么一旦我登录 LogMeIn 并可以访问计算机后它会继续。

EDIT2:直接按照流程,我运行它。这也会挂起一段荒谬的时间(通常是 5 秒,花了 200 多秒)。让我觉得硬盘决定打个盹?

private void cleanup(String path) {

    File srcPath = new File(path);
    File[] files = srcPath.listFiles();

    if(files != null) {
        for(File file : files) {
            if(file.isDirectory()) {
                cleanup(file.getAbsolutePath());
            } else {
                if(file.getAbsolutePath().endsWith(".original")) {
                    String fileName = file.getAbsolutePath().substring(0,     file.getAbsolutePath().lastIndexOf(".original"));
                    IO.delete(fileName);
                    if(!IO.renameFile(file.getAbsolutePath(), new File(fileName).getAbsolutePath())) {
                        Log.writeLogSevere("Failed to rename file, this could be a problem..." + fileName);
                    } else {
                        Log.writeLog("Cleaned up: " + fileName);
                    }
                }
            }
        }
    }
}
4

2 回答 2

1

您没有耗尽错误流。你在最后才这样做,这通常可能为时已晚。进程的输出缓冲区已满,进程阻塞等待在stderr输出缓冲区中获得更多空间。

您必须为此使用单独的线程,或者(更简单)redirectErrorStream使用ProcessBuilder.

于 2013-08-07T14:21:24.767 回答
0

最有可能的是,正在运行的线程p没有死,p.getInputStream()也不是空的,但不是它上面的数据。

当它挂起时,我会检查当前正在运行的进程(psUnix 上的命令)或 Windows 上的任务管理器。这将告诉您是否p已完成。如果不是,那么无论该程序是什么,都有问题并且它会阻止您的其余代码。

于 2013-08-07T14:14:58.380 回答