views:

491

answers:

4

I am working with ImageMagick and am wondering what the best way to read image data in from StdOut of the ImageMagick process.

I an invoking the command to the process like so: /opt/local/bin/convert -resize 8000@ - -

and then piping a byte array to the process for processing.

what is the best way to read data from a process like this?

+1  A: 

The Runtime.exec() method returns a Process that has methods for getting the input, output and error streams of the invoked process.

I do wonder how you managed to "pipe a byte array to the process" in any other way.

Note that you'll have to use multiple threads to handle the input and the output of the spawned process because it will block if you try to "pipe in" a lot of input without reading any output.

Michael Borgwardt
+2  A: 

You might want to look at Apache Commons Exec this gives you a good way of running executables and passing the results into Java.

It's similar to using the method Michael mentioned except should allow you more control.

There are some good examples of usage on the tutorial page.

Mark Davidson
Thanks, my problems were mostly between the chair and keyboard and due to hacking way too late in the night. However, your tip for Apache Exec paid off and improved the quality of the solution.
DanielHonig
+1  A: 

If you do want to use Runtime.exec(), please review this question as runtime.exec() can be a bit tricky.

You will be wanting to change the StreamGobbler for OUTPUT into something that stores stdout in an array or some such. And start the threads before doing waitFor() to prevent, as Michael said, blocking.

extraneon
A: 

Just want to post a code sample using ImageMagick via Apache commons exec for completeness

    try {

        StringBuffer sb = new StringBuffer();
        sb.append(this.validPathToImageMagickCommand);
        sb.append('\u0020');
        for (int i = 0; i < args.size(); i++) {
            String s = args.get(i);
            sb.append(s);
        }


        CommandLine cl = CommandLine.parse(sb.toString());

        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(output, System.err, new ByteArrayInputStream(inputBytes));
        byAs = new ByteArrayInputStream(inputBytes);
        pumpStreamHandler.setProcessOutputStream(byAs);

        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(pumpStreamHandler);
        int exitValue = executor.execute(cl);

        outputBytes = output.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (byAs != null)
                byAs.close();

            if (output != null)
                output.close();

        } catch (IOException e) {
            System.out.println(e);
        }

    }
DanielHonig