2

我不知道这是否可能,但可以尝试一下。
我在我的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。

4

1 回答 1

3

这有两个部分:

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

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

STDOUT->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);
}
于 2013-09-24T09:14:46.420 回答