Java 使BufferedReader不等待进程完成

Java 使BufferedReader不等待进程完成,java,process,bufferedreader,Java,Process,Bufferedreader,我得到了一个在unix(shell脚本)下运行的进程。此脚本持续运行,每秒生成更多输出 现在,我尝试使用Java中的BufferedReader获取它的当前输出。现在我意识到这一个正在等待过程的完成,所以它永远在等待 否则我怎么能意识到这一点?我只想以字符串的形式获取进程p的当前输出 我现在得到的是: Process p = Runtime.getRuntime().exec("./myScript.sh"); InputStream stdin = p.getInputStre

我得到了一个在unix(shell脚本)下运行的进程。此脚本持续运行,每秒生成更多输出

现在,我尝试使用Java中的BufferedReader获取它的当前输出。现在我意识到这一个正在等待过程的完成,所以它永远在等待

否则我怎么能意识到这一点?我只想以字符串的形式获取进程p的当前输出

我现在得到的是:

    Process p = Runtime.getRuntime().exec("./myScript.sh");
    InputStream stdin = p.getInputStream();
    InputStreamReader isr = new InputStreamReader(stdin);
    BufferedReader br = new BufferedReader(isr);
    String returner = "";
    String line = null;
    try {
        while ( (line = br.readLine()) != null) {
            returner += line;

        }
    }
    catch (IOException e) {
        System.err.println( "Processhandling went terribly wrong!");
        System.exit(1);
    }
谢谢你的帮助


注意,Flo

您正在将您读取的每一行追加到现有字符串中

首先,像这样附加字符串是低效的-您应该使用StringBuilder,特别是对于大的或多个字符串。您的方法将变得越来越慢(并最终填满所有内存)

您一直在追加(只要有输入数据),所以正如您所说,它永远不会完成

您需要读取一个数据块(可能一次读取一行,但这取决于您的数据),然后处理该数据块(可能在另一个线程中,以便读取和处理可以并行进行)

因此,不是:

    while ( (line = br.readLine()) != null) {
        returner += line;

    }
你需要:

    while ( (line = br.readLine()) != null) {
        processLine(line);
    }

其中,
processLine()
对数据做了一些有用的处理。

由于您得到的是连续输出,下面的代码将永远运行

while ( (line = br.readLine()) != null) {
    returner += line;

}

我不确定您到底想要什么…如果您的脚本将无限期运行,那么您的字符串将不断增长,进程将永远不会返回。

现在它将永远运行,因为没有理由停止。 如果您在代码中添加以下内容,您可能会达到您想要达到的目的

例如,您可以按如下方式设置停止的条件:

boolean hasReachedGoal = false;
while ( !hasReachedGoal && (line = br.readLine()) != null) {
    hasReachedGoal = line.contains("the string i was looking for")
    returner += line;
}

BufferedReader不会等待进程完成,但您的while循环会等待。如果这个过程永远运行,那么“当前输出”是什么意思呢?您关于使用StringBuilder的建议完全正确,但是javac在字节码级别上可以为您提供很多“智能”功能。编译器将发出最终生成字符串的代码,但可以自由选择如何生成。你可以自己核实我说的话。编译以下代码:
public类Teste{public static void main(String[]args){String test=”“;for(final String arg:args)test+=arg;System.out.println(args);}
然后通过
javap-c test
对其进行反编译。编译器发出了一个StringBuilder(对吗?;)是的但是在这种情况下,为什么像用字符串编写的OP这样的代码比用StringBuilder显式编写的代码运行慢很多很多倍(数千?)?我读字节码的速度不够快,但是像OPs这样的代码似乎在每次迭代中都会创建一个StringBuilder,以便将新旧字符串连接起来——因此,在循环之外创建单个StringBuilder的速度仍然非常缓慢。