我创建了一个包含2个Jar文件的Java应用程序。 Jar1用于初始化和运行Jar2,使用以下代码:
Process process = runtime.exec( "java -jar Jar2.jar" );
printLogs( process );
.
.
.
private static boolean printLogs( Process process ) {
try {
BufferedInputStream logStream = new BufferedInputStream( process.getInputStream() );
String logs = "";
int buffer = 0;
while ( ( buffer = logStream.read() ) != -1 ) {
logs += (char)buffer;
}
if( !logs.isEmpty() ) logger.debug( logs );
} catch (IOException e) {}
return true;
}
我使用Log4J从Jar2打印了许多日志,即
logger.debug( "..." );
但Jar2中的所有日志都没有打印到控制台。我弄明白了,因为日志被返回到Jar1而不是控制台,所以我使用上面的代码打印了返回的流。现在日志打印正常,但在所有Jar2进程结束后,所有日志都会立即打印在Jar1中。
问题是:我可以及时打印Jar2中的每个日志行而不是等待所有Jar2进程结束吗?
因为Jar2是一个漫长的过程,所以在应用程序处理过程中我能看到这些日志非常重要。
答案 0 :(得分:2)
整件事情搞得一团糟。您不需要两个单独的档案和Runtime.exec()
但是,通常使用BufferedReader.readLines
来读取文本行。请注意,如果您在读取每一行时记录问题,问题就会消失:
BufferedReader input = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line = null;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
您的代码等待子进程完成,因为您在流结束后记录了该行(即在子进程终止后)
这是一个演示程序,它使用长时间运行的Ruby程序作为监视过程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Subprocess {
static final String[] program = new String[] {
"ruby",
"-e" ,
"(1..5).each{|i|sleep 1;puts i;STDOUT.flush}"
};
public static void main(String[] args) throws IOException {
ProcessBuilder builder = new ProcessBuilder(program);
builder.redirectErrorStream();
Process child = builder.start();
String line = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(child.getInputStream()));
while ((line = in.readLine()) != null)
System.out.println(line);
}
}
答案 1 :(得分:0)
您的代码似乎在等待logStream
在实际编写日志之前到达EOF
(在进程退出时会发生)。尝试重构它以逐个字符地读取它,然后在看到换行符时记录累积的字符缓冲区(当然还有EOF
- 所以你得到最后一行)。
答案 2 :(得分:0)