【问题标题】:Continuous response from perl to java program从 perl 到 java 程序的持续响应
【发布时间】:2013-09-24 17:14:46
【问题描述】:

我不知道这是否可能,但想尝试一下。
我正在我的 java 程序中执行一个小的 perl 代码,就像这样

private void executePerlCode() {
    Process process;
    ProcessBuilder processBuilder;
    BufferedReader bufferedReader = null;
    try {
        // this line is used to execute the perl program
        processBuilder = new ProcessBuilder("perl", "D:\\test\\loop.pl");
        process = processBuilder.start();

        // To get the output from perl program
        bufferedReader = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        String line;
        StringBuffer str = new StringBuffer();
        while ((line = bufferedReader.readLine()) != null) {
            str.append(line);
            System.out.println(line);
        }
        // process.waitFor();

        // Set the output on the textfield
        // jTextArea1.setText(str.toString());

    } catch (Exception e) {
        System.out.println("Exception: " + e.toString());
    } finally {
        try {
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

而我的 perl 代码是

for (my $i=0; $i <= 9; $i++) {
print "$i\n";
sleep(1);
}

我能够在我的 java 程序中获得 perl 程序的输出。但我希望 perl 代码为 java 代码提供连续输出。像这样,当 perl 中的循环第一次打印 'i' 的值时,我应该能够在 Java 代码中获得该值。这样我就可以根据 Perl 代码中的流程不断更新我的 Java UI。

【问题讨论】:

  • 那么你的设计有点缺陷。现在你正在从另一个执行一个进程(perl)。因此,当 perl 程序完成时,它会返回一个响应。如果你想要 continuous 的东西,你需要编写一些 perl 来与 java 对话,可能是在命名管道或一些公共存储上。
  • @Gideon :是的,这正是我想要的,但不知道该怎么做。你能分享一些实现这个东西的例子吗?
  • 当然可以。唯一阻止您这样做的是代码中的process.waitFor(); 行(它一直等到进程终止)。
  • 已删除 process.waitFor(),但仍无法按预期工作。
  • 那么你现在对每一行都做些什么吗? setText() 调用是否在循环内?

标签: java swing perl


【解决方案1】:

这有两个部分:

  1. 确保 Perl 输出没有被缓冲以便输出立即可用
  2. 让 Java 不断地从 Perl 中读取。

为确保 Perl 输出不被缓冲,您需要在 for 之前添加以下行:

STDOUT-&gt;autoflush(1);

使 Java 连续读取更具挑战性,方法的细节将取决于您打算如何处理输出。

下面是一个示例,只需将子进程的输出重定向到 Java 的输出。

首先,需要一个扩展 Thread 的类来处理衍生进程的输出:

package com.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class StreamRedirector extends Thread {

  private InputStream inputStream;
  private OutputStream outputStream;

  public StreamRedirector(InputStream inputStream, OutputStream outputStream) {
    this.inputStream = inputStream;
    this.outputStream = outputStream;
  }

  public void run() {
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    String line = null;
    try {
      while ((line = bufferedReader.readLine()) != null) {
        outputStreamWriter.write(line + "\n");
        outputStreamWriter.flush();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

然后可以生成该进程。在本例中,主代码立即等待衍生进程退出:

Runtime rt = Runtime.getRuntime();

Process proc;
try {
  proc = rt.exec(command);
} catch (IOException e) {
  throw new CustomException("Failed to execute.", e);
}

StreamRedirector outStreamRedirector = new StreamRedirector(proc.getInputStream(), System.out);
StreamRedirector errStreamRedirector = new StreamRedirector(proc.getErrorStream(), System.err);

outStreamRedirector.start();
errStreamRedirector.start();

int exitVal;
try {
  outStreamRedirector.join();
  errStreamRedirector.join();
  exitVal = proc.waitFor();
} catch (InterruptedException e) {
  throw new CustomException("Failed to execute.", e);
}

【讨论】:

  • 非常感谢。我现在可以在 java 控制台上看到输出了 :-)
  • 但是我们为什么要告诉 perl 不要缓冲内容呢?如果您在 shell 上执行相同的 perl 脚本,它工作得非常好,输出立即可用。为什么从 Java 执行时会有所不同?
  • 顺便说一句,我有一个简单的 shell 脚本,它每 5 秒打印一次,它在 shell 和 Java 上运行良好,输出永远不会被缓冲,它可以立即供另一端使用。但是,在 perl 脚本中执行的相同操作具有不同的效果。 perl 脚本通过立即打印输出在 shell 上运行良好,但是当从 Java 进程执行时输出被缓冲。
  • 我们要求 perl 不要缓冲,以便 java 不必处理部分行。这更像是一种预防措施,但在某些情况下,它可以避免奇怪的问题。
猜你喜欢
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 2013-01-11
  • 2012-11-27
相关资源
最近更新 更多