views:

126

answers:

5

I have a UNIX native executable that requires the arguments to be fed in like this

prog.exe < foo.txt.

foo.txt has two lines: bar baz

I am using java.lang.ProcessBuilder to execute this command. Unfortunately, prog.exe will only work using the redirect from a file. Is there some way I can mimic this behavior in Java?

Of course,

ProcessBuilder pb = new ProcessBuilder("prog.exe", "bar", "baz"); 

does not work.

Thanks!

A: 

Did you try to wrap prog.exe into a script which accepts arguments and deal with prog.exe ? I assume you're using a shell, so it's quite simple to set up a bash script.

If I understand your problem, the script would look like :

#!/usr/bin/bash
echo $1 > file
echo $2 >> file
prog.exe < file
remove file
Rob
That would be fine but the point of this is to port from UNIX to Windows. So I won't have a shell on the new platform.
initialZero
+1  A: 

The redirection is setup by the shell you need todo this manually, something like that:

Process proc = pb.start();
OutputStreamWriter os = new OutputStreamWriter(proc.getOutputStream());
// then write the data from your file to os
// ...
os.close();
stacker
+3  A: 
ProcessBuilder pb = new ProcessBuilder("prog.exe");
Process p = pb.start();
OutputStream pos = p.getOutputStream();

InputStream fis = new FileInputStream("file.txt");
byte[] buffer = new byte[1024];
int read = 0;
while((read = fis.read(buffer)) != -1) {
    pos.write(buffer, 0, read);
}
fis.close();

Not tested, but something like this should work.

Marc
A: 

Build the process using a ProcessBuilder, then use process.getOutputStream() to get an OutputStream that will pipe to the standard input of the process.

Open the file using normal Java techniques, read the contents of the file and write it to the OutputStream going to the Process you made with the ProcessBuilder.

The problem you have right now is that you're calling the ProcessBuilder to launch

$ prog.exe foo bar

Which is probably nothing close to what you want to achieve.

Edwin Buck
A: 

I ended up doing something like this and it works. Thanks for all the help!

    import java.io.BufferedWriter;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.util.LinkedList;
    import java.util.List;

    public class UserInp {

        public static void main(String[] args) {
            new UserInp().sample();
        }

        public void sample() {

            String command = "foo.exe";

            List<String> args = new LinkedList<String>();

            args.add("bar");
            args.add("baz");

            ProcessBuilder pb = new ProcessBuilder(command);
            java.lang.Process process = null;

            try {
                process = pb.start();
            } catch (IOException ex) {
                //--
            }
            OutputStream os = process.getOutputStream();
            PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)));

            final InputStream is = process.getInputStream();
            new Thread(new Runnable() {
                public void run() {
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        String line;
                        while ((line = br.readLine()) != null) {
                            System.out.println(line);
                        }
                    } catch (java.io.IOException e) {
                    }
                }
            }).start();

            for (String arg : args) {
                pw.println(arg);
            }

            pw.close();

            int returnCode = -1;
            try {
                returnCode = process.waitFor();
            } catch (InterruptedException ex) {
                //--
            }
            System.out.println(returnCode);
        }
    }
initialZero