dariober
dariober

Reputation: 9062

Java prog piped and returned immediately

I have a Java program that prints to stdout. If the output is piped to, say, head the shell doesn't return immediately after head has done its job, instead it waits for the Java program to complete all its work.

So my question is: How can I write the Java program so that the shell returns immediately, just like cat ... | head?

This is an example for what I mean:

Here the shell returns immediately as head takes no time to print the first ten line, no matter how big bigfile.txt is:

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

Here instead the first ten lines are quickly printed but the shell doesn't return until all the file is processed:

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

DummyReader.jar is as simple as I could make it:

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);
    }

}

My settings:

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)

On MacOS 10.6.8

Upvotes: 4

Views: 67

Answers (1)

Russell Reed
Russell Reed

Reputation: 464

It's just because you're not checking for errors after the println call. Here's a revised version that does stop. It will be slower, though, because checkError() flushes any output that has been buffered so far.

There may be other ways to get notified about the error without the slowdown. I've seen some code that explicitly handles the SIGPIPE signal, but I don't know if that's the best way to do it.

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);
    }

}

Upvotes: 2

Related Questions