How to pipe InputStream to ProcessBuilder

Hrishikesh Choudhari picture Hrishikesh Choudhari · Jun 28, 2012 · Viewed 24.5k times · Source

Please move down to the 2nd update. I didn't want to change the previous context of this question.

I'm using wkhtmltoimage from a Java app.

The standard way of using it is - path-to-exe http://url.com/ image.png.

According to their docs, if we write a - instead of an input URL, the input shifts to STDIN.

I'm starting the process using ProcessBuilder -

ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path);

Process process = pb.start();

Now I'm unable to figure out how to pipe an input stream to this process.

I have a template file read into a DataInputStream, and I'm appending a string at the end:

DataInputStream dis = new DataInputStream (new FileInputStream (currentDirectory+"\\bin\\template.txt"));
byte[] datainBytes = new byte[dis.available()];
 dis.readFully(datainBytes);
 dis.close();

 String content = new String(datainBytes, 0, datainBytes.length);

 content+=" <body><div id='chartContainer'><small>Loading chart...</small></div></body></html>";

How do I pipe content to the STDIN of the process?

UPDATE---

Following the answer by Andrzej Doyle:

I've used the getOutputStream() of the process:

ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path);

    pb.redirectErrorStream(true); 

    Process process = pb.start();         

    System.out.println("reading");

    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

    bw.write(content);

Doing so gives an error saying:

Exception in thread "main" java.io.IOException: The pipe has been ended

2nd UPDATE--------

The current code block is as such:

    try {
        ProcessBuilder pb = new ProcessBuilder(full_path, "--crop-w", width, "--crop-h", height, " - ", image_save_path);
        System.out.print(full_path+ "--crop-w"+ width+ "--crop-h"+ height+" "+ currentDirectory+"temp.html "+ image_save_path + " ");
        pb.redirectErrorStream(true); 

        Process process = pb.start(); 
        process.waitFor();
        OutputStream stdin = process.getOutputStream();

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
// content is the string that I want to write to the process.

        writer.write(content);
        writer.newLine();  
        writer.flush();
        writer.close();


    } catch (Exception e) {
        System.out.println("Exception: " + e);
        e.printStackTrace();
    }

Running the above code gives me an IOException: The pipe is being closed.

What else do I need to do to keep the pipe open?

Answer

Peter Lawrey picture Peter Lawrey · Aug 7, 2012

Exception in thread "main" java.io.IOException: The pipe has been ended

This means the process you have started has died. I suggest you read the output to see why. e.g. did it give you an error.