我正在使用标准代码读取单独的进程控制台输出:
ProcessBuilder b = new ProcessBuilder(exeArgs);
b.redirectErrorStream(true);
Process process = b.start();
try (BufferedReader inputReader= new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String output;
while ((output = inputReader.readLine()) != null) {
// do something with output
}
}
问题是如果进程比我读取输出的结束速度快,则输出的一部分会丢失。
重现问题的最简单方法是在try
表达式上放置一个断点并等待一秒钟,然后再继续执行程序。这样做会阻止您获得任何输出。例如。 inputReader.readLine()永远不会返回字符串。
是否有办法缓存流程输出以确保它始终完全读取?
答案 0 :(得分:0)
在Windows上,控制台缓冲区的大小似乎是有限的,您应该尽快读取它,以避免缓冲区溢出和丢失部分数据。在阅读了几个答案并阅读了有关该主题的博客文章之后,我找到的唯一可靠的解决方案是尽快在单独的线程中读取控制台输出。
这是在Kotlin中实现任务的简单代码:
typealias GobblerCallback = ((e: String) -> Unit)
class StreamGobbler(private val stream: InputStream, private val lineReadCallback: GobblerCallback? = null) : Thread() {
override fun run() {
try {
val reader = BufferedReader(InputStreamReader(stream, StandardCharsets.UTF_8))
while (true) {
val line = safeReadLine(reader) ?: break
lineReadCallback?.invoke(line)
}
} catch (e: Exception) {
// Handle exception if necessary
}
}
}
// Sample code that reads full process output
val gobbler1 = StreamGobbler(process.inputStream, callback)
gobbler1.start()
val gobbler2 = StreamGobbler(process.errorStream, callback)
gobbler2.start()