Java,读取和写入Autoit脚本的输入和输出流

时间:2013-01-07 02:23:06

标签: java inputstream outputstream autoit

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

的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

1 个答案:

答案 0 :(得分:1)

我不是这方面的专家,不是以任何方式,而是考虑这些变化:

  • Autoit ConsoleRead()的一个问题是它没有阻塞,我认为不能识别新行。换句话说,它的行为与Java的Scanner.nextLine()没有任何相似之处。
  • 实际上它可能同时读了很多行,我不确定这是否可以预测。
  • 考虑使用AutoIt的StringSplit(...)函数将@CRLF作为分隔符拆分行,然后使用ConsoleWrite(...)
  • 将结果数组中的每个String推送到标准输出
  • 考虑让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();
   }
}

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