1

出力ストリームに書き込み、単純な Autoit スクリプトの入力ストリームを読み取ろうとしています。newLine() 文字を使用しない場合、期待どおりの出力が得られます。1 行が auto it に送信され、1 行が 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();
   }
}

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
于 2013-01-09T00:47:19.980 に答える