Java编程管道并立即返回

时间:2014-12-21 14:31:46

标签: java shell pipe

我有一个打印到stdout的Java程序。如果输出通过管道传递给head,那么shell在完成其工作后不会立即返回,而是等待Java程序完成其所有工作。

所以我的问题是:如何编写Java程序以便shell立即返回,就像cat ... | head一样?

这是我的意思的一个例子:

这里shell立即返回,因为head没有时间打印前十行,无论bigfile.txt有多大:

time cat bigfile.txt | head
...
real    0m0.079s
user    0m0.001s
sys     0m0.006s

在这里,前十行快速打印,但shell在处理完所有文件之前不会返回:

time java -jar DummyReader.jar bigfile.txt | head
...
real    0m18.720s
user    0m16.936s
sys     0m2.212s

DummyReader.jar就像我能做到的那样简单:

import java.io.*;

public class DummyReader {

    public static void main(String[] args) throws IOException {

        BufferedReader br= new BufferedReader(new FileReader(new File(args[0])));   
        String line;
        while((line= br.readLine()) != null){
            System.out.println(line);
        }
        br.close();
        System.exit(0);
    }

}

我的设置:

java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-10M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

在MacOS 10.6.8上

1 个答案:

答案 0 :(得分:2)

这只是因为你在println调用后没有检查错误。这是一个停止的修订版本。但是它会慢一点,因为checkError()会刷新到目前为止已缓冲的任何输出。

可能有其他方法可以在没有减速的情况下获得有关错误的通知。我已经看到一些显式处理SIGPIPE信号的代码,但我不知道这是否是最好的方法。

import java.io.*;

public class DummyReader {

    public static void main(String[] args) throws IOException {

        BufferedReader br= new BufferedReader(new FileReader(new File(args[0])));   
        String line;
        int linecount = 0;
        while((line= br.readLine()) != null){
            System.out.println(line);
            if (System.out.checkError())
            {
                System.err.println("Got some sort of error in the output stream");
                break;
            }
            linecount++;
        }
        br.close();
        System.err.println("Read " + linecount + " lines.");
        System.exit(0);
    }

}