tombo_189 tombo_189 - 2 months ago 26x
Java Question

Writing to the OutputStream of Java Process/ProcessBuilder as pipe

I have problems sending data from java to a (linux)-subprocess created by ProcessBuilder/Process.

A shell-only based basic example would look like as follows and works fine.

echo "hello world" | cat - >/tmp/receive.dat

Now, I want to substituted the
echo "hello world"
by a java program which should internally create a new process (the
cat - >/tmp/receive.dat
) and then send data to it.

I tried the following, but the file
remains untouched:

String[] cmdArray = { "/bin/cat", "-", ">/tmp/receive.dat" };
ProcessBuilder builder = new ProcessBuilder (cmdArray); (new File ("/tmp"));
Process p = builder.start ();
OutputStream pos = p.getOutputStream ();

byte [] bytes = "hello world".getBytes ();
pos.write (bytes);
pos.close ();
p.waitFor ();

The same happens under Windows, of course with an adapted cmdArray:

cmd /c type con >c:\tmp\receive.dat

Printing directly to system.out from java is no alternative as many subprocesses should be called within the livecycle of the java program.

thx for any help!


The issue here is that /bin/cat does not actually write to files, it merely writes to standard out. The output redirection >/tmp/receive.dat is actually performed by the shell, but you are bypassing the shell by invoking cat in this manner.

If what you are trying to achieve is merely an OutputStream that writes to a file, then doing that via standard java I/O (e.g., FileOutputStream and friends) is what you want. It is also cross-platform (i.e., Windows-friendly), unlike anything that depends on the shell.

Regarding the comment about not being able to merely write to standard out from java because of subprocesses - any subprocess you invoke can inherit standard out from their parent process (the java process - look at ProcessBuilder.Redirect.INHERIT). So even if you are invoking subprocesses from java, redirecting all the output to a file should still work in the same way as your initial example (where the java program replaces the echo command).