2016-10-07 1 views
4

私はユーザ名と年齢として入力を受け取り、両方の入力をプリントするバッチスクリプトを持っています。私はそのスクリプトを実行し、入力を渡すjavaプログラムを書いています。Java Process Builderを使用して複数の入力を受け取るバッチスクリプトを実行するには?

私はProcessBuilderを使用してJavaプログラムを作成しました。私はまた、プロセスのOutputStreamでユーザー名と年齢を渡していますが、ユーザー名だけが印刷され、年齢が表示されません。

私のスクリプト(TEST.BATファイル):

@echo off 
echo executing test.bat 
set /p name=Enter Name: 
set /p age=Enter Age : 
echo Hi %name%, you are %age% years old. 

私のJavaプログラム:

private static void executeInteractiveCommand(String cmd,String ... args){ 
    try{ 
     List<String> command = new ArrayList<String>(); 
     command.add(cmd); 
     ProcessBuilder builder = new ProcessBuilder(command); 
     Map<String, String> environ = builder.environment(); 
     final Process process = builder.start(); 
     OutputStream out = process.getOutputStream(); 
      out.write("tester \n\r".getBytes()); 
      out.flush(); 

      out.write("25\n".getBytes()); 
      out.flush(); 
      out.close(); 

      int errCode = process.waitFor(); 

      System.out.println("Process Error Code : "+errCode); 

      InputStream is = process.getInputStream(); 
      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader br = new BufferedReader(isr); 
      String line; 
      while ((line = br.readLine()) != null) { 
       System.out.println(line); 
      } 
      //out.close(); 
      is.close(); 
      System.out.println("Program terminated!"); 
      }catch(IOException ex){ 
       ex.printStackTrace(); 
      } catch(InterruptedException ex){ 
       ex.printStackTrace(); 
      } 
     } 
+0

が出力されます: のjavaにTestScript プロセスエラーコード:年齢を入力してください:0 TEST.BAT 名を入力し実行こんにちはテスターを、あなたは歳です。 プログラムが終了しました。 –

答えて

-1

あなたはこのコードを試すことができます。この質問は、stackoverflow上の誰かからも尋ねられるので、完璧に実行されます。

+0

execコマンドの 'start'パラメータでは、プロセスストリームが古いものに接続されている間に新しいcmdウィンドウで開始されるため、目的のプロセスと対話する能力が失われます。実際には、あなたのソリューションを完全に無意味にするプロセスにいくつかの入力をパイプしません。 – ArcticLord

+0

@ArcticLordはい私はそれを知っていますが、上記の質問は、問題を実行するための代替ソリューションを提供することを要求していません。 – legend

+1

OPは、Javaプログラム内から入力をバッチファイルにパイプする方法のヘルプを要求します。あなたはあなたの "代替ソリューション"でその方向に何もしません。だから本当に役に立たない。 – ArcticLord

2

バッチスクリプトに2つの入力を個別にフラッシュしてストリームを閉じます。その結果、スクリプトは最初の入力のみを消費します。ストリームが閉じられているので、残りのすべてのSET /Pステートメントを空にしてパイプに残っている実際の入力を無視します。そして、問題は:なぜですか?

SET /Pコマンドがどのように詳細に機能するか、実行中の入力プロンプトセッションが終了する条件が存在するかどうかを分析するthis articleが見つかりました。

最後の2文字が、これは通常の場合とれる好ましいものであるCRLF
ある読み取ります。入力がパイプされていないがユーザーによって入力された場合、ENTERキーがヒットした時点で入力が終了します。次に、CRLFトークンが設定され、入力が消費されます。私たちのJavaパイプでは、Stringの末尾に\r\nを追加することで同じことができます。しかし、どういうわけか、これはうまくいかず、理由を理解できませんでした。

タイムアウト
非常に単純な回避策は、入力間にある程度の時間を置くことです。結果は、スクリプトが次の入力の前に各入力を消費することになります。あなたが2つの入力の間にあなたが追加するならば、あなたが2つの入力はすべて期待どおりに動作します。

フルバッファ
SET /Pステートメントの入力は1024文字に制限されています。これを使用して1024より小さい1つのchar型のバッファをパイプすることで状況を解決することができます。次の入力の最初の文字はバッファをいっぱいにし、入力を消費し、次の文に進みます。 この変換方法を使用する場合

public static byte[] convert(String str){ 
    byte[] asBytes = str.getBytes(); 
    byte[] result = new byte[1023]; 
    for(int i = 0; i < asBytes.length; i++) 
     result[i] = asBytes[i]; 
    return result; 
} 

コードは期待通りに動作します。実際には、フラッシングを外すことさえできます。

OutputStream out = process.getOutputStream(); 
out.write(convert("tester")); 
out.write(convert("25")); 
out.close(); 
+0

ご協力いただきありがとうございます。睡眠を取った後、私は希望の結果を得ています。 –

+0

Thread.sleep(100)を使用せずに行うことはできますか? –

+0

@RajeshKumar実際にはいです。私はいくつかの研究をしました。私の編集を参照してください。 – ArcticLord

0

あなたは、第二のように2%とし、1%で、最初の引数を読み取ることができ、あなたのバッチファイルでコード

'Runtime runtime = Runtime.getRuntime(); 
Process proc = null; 
String executionarr[] = { batchfileName, arg1, arg2}; 
proc = runtime.exec(executionarr);' 

下に試すことができます。ここ

関連する問題