1

我正在尝试写入输出流并读取简单 Autoit 脚本的输入流。如果我不使用 newLine() 字符,我会得到预期的输出:发送一行来自动处理它,发送一行到 java,然后重复。如果我添加 newLine() 字符,似乎每个周期都会向 autoit 发送额外的一行。为什么会这样?

自动:

Local $line

While (True)

    $line = ConsoleRead()

    ConsoleWrite( $line & "to java" & @LF )

    Sleep(25)

WEnd

爪哇:

p = Runtime.getRuntime().exec("Test");

in = new BufferedReader( new InputStreamReader(p.getInputStream()));
out = new BufferedWriter( new OutputStreamWriter(p.getOutputStream()));

int i=0;

out.write("(" + i++ + ") to autoit");
out.newLine();
out.flush();

while ((line = in.readLine()) != null) {

    System.out.println(line);

    out.write("(" + i + ") to autoit");
    out.newLine();
    out.flush();

    if(i++ > 9)
        p.destroy();
}

输出:

(0) to autoit
to java
(1) to autoit
(2) to autoit
to java
(3) to autoit
(4) to autoit
(5) to autoit
to java
(6) to autoit
(7) to autoit
(8) to autoit
(9) to autoit
to java

我预期的输出:

(0) to autoit
to java
(1) to autoit
to java
(2) to autoit
to java
(3) to autoit
to java
(4) to autoit
to java
(5) to autoit
to java
(6) to autoit
to java
(7) to autoit
to java
(8) to autoit
to java
(9) to autoit
to java
4

1 回答 1

1

我不是这方面的专家,无论如何都不是,但请考虑以下变化:

  • Autoit 的一个问题ConsoleRead()是它没有阻塞,我相信它不能识别新行。换句话说,它的行为与 Java 的 Scanner.nextLine() 没有任何相似之处。
  • 实际上,它可能会同时读入一大堆行,我不确定这是否可以预测。
  • 考虑使用 AutoIt 的StringSplit(...)函数以使用 @CRLF 作为分隔符拆分行,然后使用将结果数组中的每个字符串推送到标准输出ConsoleWrite(...)
  • 考虑让 AutoIt 使用该StringInStr(...)函数来测试告诉它退出的令牌。
  • 在 Java 方面,我认为您需要在与您编写的线程不同的线程上从标准中读取文本,以免阻塞。
  • 我已经使用 Scanner 来解析标准输入,并且喜欢使用 PrintStream 来轻松输出到标准输出。

例如:

EchoCaller2.java

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;

public class EchoCaller2 {
   private static final String AUTO_IT_ECHOER = "Echoer.exe"; // AutoIt program
   private static Scanner scan = null;
   private static PrintStream out = null;

   public static void main(String[] args) throws IOException,
         InterruptedException {
      ProcessBuilder pb2 = new ProcessBuilder(AUTO_IT_ECHOER);
      pb2.redirectErrorStream();
      Process p = pb2.start();
      scan = new Scanner(p.getInputStream());
      out = new PrintStream(new BufferedOutputStream(p.getOutputStream()));

      new Thread(new Runnable() {
         public void run() {
            while (scan.hasNextLine()) {
               System.out.println(scan.nextLine());
            }
            scan.close();
         }
      }).start();

      for (int i = 0; i < 10; i++) {
         out.println("(" + i + ") to autoit ");
         out.flush();
      }

      out.println("exit ");
      out.flush();
      out.close();
   }
}

回声.au3

Local $line

While (True)

    $line &= ConsoleRead()

    $strArray = StringSplit($line, @CRLF)

    If $strArray[0] > 0 Then
        For $r = 1 to $strArray[0]
            If StringLen($strArray[$r]) > 0 Then
                ConsoleWrite($strArray[$r] & "to java" & @CRLF)
            EndIf
        Next
    EndIf

    If StringInStr($line, "exit") Then
        Exit
    EndIf

    $line = ""

    Sleep(25)

WEnd
于 2013-01-09T00:47:19.980 回答