将 Java Process/ProcessBuilder 的 OutputStream 作为管道写入 [英] Writing to the OutputStream of Java Process/ProcessBuilder as pipe

查看:291
本文介绍了将 Java Process/ProcessBuilder 的 OutputStream 作为管道写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将数据从 java 发送到由 ProcessBuilder/Process 创建的 (linux) 子进程时遇到问题.

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

仅基于 shell 的基本示例如下所示并且可以正常工作.

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

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

现在,我想用一个 Java 程序替换 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.

我尝试了以下操作,但文件 /tmp/receive.dat 保持不变:

I tried the following, but the file /tmp/receive.dat remains untouched:

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

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

在 Windows 下也会发生同样的情况,当然使用经过调整的 cmdArray:

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

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

从 java 直接打印到 system.out 是无可替代的,因为在 java 程序的生命周期内应该调用许多子进程.

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

感谢您的帮助!通博

推荐答案

这里的问题是 /bin/cat 实际上并不写入文件,它只是写入标准输出.输出重定向>/tmp/receive.dat 实际上是由shell 执行的,但是您通过以这种方式调用cat 绕过了shell.

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.

如果您想要实现的只是一个写入文件的 OutputStream,那么通过标准 Java I/O(例如 FileOutputStream 和朋友)来实现就是您想要的.它也是跨平台的(即对 Windows 友好),不像任何依赖于 shell 的东西.

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.

关于由于子进程而不能仅仅从 Java 写入标准输出的评论 - 您调用的任何子进程都可以从其父进程(Java 进程 - 查看 ProcessBuilder.Redirect.INHERIT).因此,即使您从 java 调用子进程,将所有输出重定向到文件仍应以与初始示例相同的方式工作(java 程序替换 echo 命令).

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).

这篇关于将 Java Process/ProcessBuilder 的 OutputStream 作为管道写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆