Java ProcessBuilder未写入换行符致sed进程阻塞问题
解决Kotlin调用sed进程阻塞无输出的问题
我来帮你捋清楚这个问题~你遇到的核心原因其实是sed的行缓冲机制和输入流未正确关闭导致的:
sed是按行处理输入的工具,它默认会缓存输入内容,直到收到完整的换行符或者检测到输入结束(EOF)才会处理并输出结果。你的代码里虽然写入了带换行符的内容,但如果没有明确告知sed“输入已经全部传完了”,它会一直等着更多输入,自然不会输出任何内容,进程也不会终止,最终导致BufferedReader的readLine()一直阻塞。
具体解决方法
这里给你两个可行的处理方式:
写完数据后关闭输出流
这是最直接的方法,当你把所有要传递给sed的内容写完后,调用close()关闭进程的输出流,这样sed就会收到EOF信号,处理剩余的行并输出结果。示例代码:val process = ProcessBuilder("sed", "s/bla/blub/").start() val writer = BufferedWriter(OutputStreamWriter(process.outputStream)) // 写入预期的输入内容 writer.write("bla\nblaa\n") // 关键:关闭输出流,告知sed输入已结束 writer.close() // 读取并处理sed的输出 val reader = BufferedReader(InputStreamReader(process.inputStream)) var line: String? while (reader.readLine().also { line = it } != null) { println(line) } // 等待进程结束 process.waitFor()手动刷新缓冲区(按需使用)
如果你的场景需要持续向sed写入数据,暂时不想关闭流,可以调用writer.flush()强制把缓冲区的内容发送给sed。但要注意,即使刷新了缓冲区,sed还是会等到换行符或者输入结束才会处理,所以这种方式适合需要分批写入但每批都带换行符的场景:writer.write("bla\n") writer.flush() // 强制发送当前缓冲区内容 writer.write("blaa\n") writer.flush() // 所有内容写完后依然要关闭流 writer.close()
额外排查点
- 确认你写入的换行符格式:大多数系统下sed都能识别
\n(LF)作为换行符,Windows系统下偶尔需要\r\n,但一般不是问题的核心。 - 检查是否有其他代码逻辑占用了进程的输入/输出流,导致数据没有正常传递。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

