Java BufferedReader似乎无限地读取第一行
我正试图通过我正在编写的Java应用程序运行Handbrake,但在等待Handbrake完成时遇到了麻烦 当我尝试这个:Java BufferedReader似乎无限地读取第一行,java,process,bufferedreader,handbrake,Java,Process,Bufferedreader,Handbrake,我正试图通过我正在编写的Java应用程序运行Handbrake,但在等待Handbrake完成时遇到了麻烦 当我尝试这个: ProcessBuilder builder = new ProcessBuilder( "cmd.exe", "/c", command); Process p = builder.start(); BufferedReader inputreader = new BufferedReade
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", command);
Process p = builder.start();
BufferedReader inputreader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line = inputreader.readLine()) != null)
{
System.out.println(line);
}
我得到的结果是:
Encoding: task 1 of 1, 0.00 %
一次又一次,文件永远不会被转换
当我将其更改为以下内容时:
BufferedReader inputreader = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader errorreader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = null;
String line2 = null;
while((line = inputreader.readLine()) != null && (line2 = errorreader.readLine()) != null)
{
System.out.println(line);
System.out.println(line2);
}
它在我的测试文件上工作,但是当errorreader没有足够的行可读时,它就会挂起,readLine()会无限锁定线程。在全长文件上,文件会被转换,但这部分代码会被锁定,因此它永远不会在应用程序中继续
有什么建议吗?调用
builder.redirectErrorStream(true)创建进程之前(这将把输入和错误流合并为一个:输入流),并且只从输入流读取
这将解决错误流在输入流之前耗尽数据的问题
如果您确实希望将它们分开,则可以启动两个线程,一个从输入流读取,另一个从错误流读取。我总的感觉是,您等待的进程没有机会执行,因此,您会被来自它的相同输出挂起。@TimBiegeleisen-这是我最初的想法,但当第二个工作时,我对会发生这种情况的原因感到困惑。@fftk4323-哪一块的输出?我认为是第二块。这是唯一的解释:子进程不断产生相同的数据。从stdout
和stderr
交替读取行可能无法工作,除非子进程在这两个进程上产生相同数量的行,这是极不可能的。进程输出应该在单独的线程中使用,或者通过合并流来使用。嗯,这似乎解决了这两个问题。你知道为什么这样做会使第一个管道工作吗?这不是一个确定的原因,但是:这些管道的容量有限。如果您没有读取错误流(在第一个示例中),那么它将以满结束,这意味着该过程无法继续。我猜:handbrake可能是多线程的,执行转换的线程会写入错误流。此线程被阻止,因为错误流管道已满。另一个线程将数据发送到输入流(从handbrake的角度来看是stdout输出流),并且它一直发送“0%”,因为转换线程被阻塞。这是一个有趣的想法,我必须尝试深入挖掘,看看是否可以验证导致问题的类似内容。谢谢你的意见!