这是我的工作流程:
我从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);
}
}
}
}
}
}
答案 0 :(得分:0)
最有可能的是,运行p
的线程没有死亡,p.getInputStream()
不是空的,而是没有数据。
当它挂起时,我会检查当前正在运行的进程(Unix上的ps
命令)或Windows上的任务管理器。这将告诉您p
是否完成。如果不是,那么无论该程序是什么,都有问题,并且它会占用你的其余代码。
答案 1 :(得分:0)
您没有耗尽错误流。你最后这样做,这往往为时已晚。进程的输出缓冲区填满,进程阻塞等待在stderr
输出缓冲区中获得更多空间。
您必须使用单独的线程,或使用redirectErrorStream
(更简单)ProcessBuilder
。