【问题标题】:Can't understand use of input stream and output stream看不懂输入流和输出流的使用
【发布时间】:2014-09-05 09:42:46
【问题描述】:

我对输入流和输出流的使用感到困惑。来自堆栈溢出问题confused about stdin, stdout and stderr?

标准输入 - 这是您的进程为从您那里获取信息而读取的文件句柄。

标准输出 - 您的进程将正常信息写入此文件句柄。

我试图使用 java 运行一个外部进程(一个 python 脚本)。这是一个交互式进程,需要用户输入。

现在正如概念所说:

当您的进程读取以从中获取信息时使用标准输入 你。

所以我应该从进程中获取输入流以将值写入它。我尝试了它并失败了。所以我搜索堆栈溢出给了我一个同样问题的问题,即从进程中获取输出流然后写入它。我试过了,效果很好。

我的问题是为什么它会起作用?不应该是输入流,我应该使用它来为该外部进程提供输入,或者我完全错误地理解输入流和输出流。

请通过简单的解释帮助我理解它。

编辑:我的代码是:

 Process process=Runtime.getRuntime().exec("/usr/bin/python /home/abhijeet/test.py");
    OutputStream  stdin = process.getOutputStream ();
    String line = "30" + "\n";
    stdin.write(line.getBytes() );

【问题讨论】:

    标签: java stream inputstream outputstream


    【解决方案1】:

    应用程序应始终将数据写入父进程的输出流并从父进程的输入流中读取数据。对于进程而言,每当创建子进程时,父进程都会将数据馈送到子进程输入流中,并从子进程输出流中读取数据。

    默认情况下,创建的子进程没有自己的终端或 安慰。它的所有标准 I/O(即标准输入、标准输出、标准错误)操作 将被重定向到可以访问它们的父进程 通过使用 getOutputStream() 方法获得的流, getInputStream() 和 getErrorStream()。父进程使用这些 流向子流程提供输入并从子流程获取输出。

    public abstract OutputStream getOutputStream()
    

    返回连接到正常输入的输出流 子进程。流的输出通过管道传输到 此 Process 对象表示的进程。

    应用程序将数据馈送到父进程输出流,数据将通过管道传送到子进程的输入流。

    public abstract InputStream getInputStream()
    

    返回连接到正常输出的输入流 子进程。流获取从标准输出管道传输的数据 此 Process 对象表示的进程。

    父进程从子进程的输出中读取数据。应用程序从父进程输入流中读取数据。

    在您的代码中:

    Process process=Runtime.getRuntime().exec("/usr/bin/python /home/abhijeet/test.py");
    OutputStream  stdin = process.getOutputStream ();
    String line = "30" + "\n";
    stdin.write(line.getBytes() );
    

    你运行的java程序是父进程。您运行的 python 脚本是子进程。 process.getOutputStream () 返回父进程输出流。不要在这里感到困惑。此方法不返回子流程输出流。仔细阅读我上面引用的文档。

    现在您将“30\n”写入父进程的输出流,该流现在通过管道传输到 python 脚本进程输入流中,可供脚本读取。

    【讨论】:

    • 应用程序应该总是从父进程的输入流中读取。那为什么我需要把进程的输出流传递给python脚本呢?
    • 因为要将数据传递给子进程,所以需要将数据写入子进程的输入流。因此,您需要写入父进程输出流,该输出流将通过管道传输到子进程的输入流。我猜这里你的 python 脚本执行将是子进程。
    • 我已经编辑了问题并添加了相应的代码,请您检查并简要解释一下。这将非常有帮助。
    • 更新了您的 cmets 的答案
    • 非常感谢。我对概念很清楚。我开始这个问题是因为我对输入流和输出流的使用感到困惑。我采用了这个概念,但仍然无法解决该问题。我正在使用 apache commons exec,其中父进程使用 satandard 输出进行输出。我无法将其应用到那里。看看:stackoverflow.com/questions/25680210/…
    【解决方案2】:

    OutputStream 顾名思义,用于将输出写入流(可能流到文件中,但也可能是不同类型的流)。

    InputStream 同样用于从流中读取输入。

    您可以将这些类视为同一流的两端:生产者/服务器写入输出流,消费者/客户端从输入流中读取。

    当您的进程读取数据以从您那里获取信息时,使用标准输入。

    这将从用户的角度描述流。对您而言,它是一个输出流,因为您使用控制台输入数据;对于读取该数据的进程,它是一个输入流,因为它读取您输入到流中的数据。

    一个小的可视化:

    User/Console                      Process/Application
    (OutputStream) ------ data ----> (InputStream)
    (InputStream)  <--- feedback --- (OutputStream)   
    

    【讨论】:

    • 你解释得对,但你的可视化是错误的。对于应用程序,它从中获取数据的流是输入流。
    • @Thomas :感谢您的回复。它为我清除了差异。现在我正在尝试对 apache common exec 做同样的事情,因为 succprocess 使用标准输出流(System.out)。所以我应该只做 System.out.write() 并且子进程会将它放入它的输入流中吗?我试过了,但是没有用
    • @AbhijeetPanwar 取决于进程将从哪个输入流中读取。进程不一定从标准输入读取。
    猜你喜欢
    • 2020-04-26
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    相关资源
    最近更新 更多