0

プログラムの途中でバッチファイルを実行したい(これにより別のJavaアプリが起動します)。正常に実行されたかどうかを確認したり、そのバッチファイルの実行からエラーをキャプチャしたりしたくありません。そのバッチファイルを開始した後、そのバッチを実行した後にそれを待つのではなく、他のことをしたいと思います。

stdoutとstderrの世話をする必要がありますか?stdoutとstderrの世話をする方法はありますか。

これは、このトピックに関する私の混乱を解消するための2回目の投稿です。質問に具体的に記入し、process.exeまたはprocessbuilderの方法へのリンクをスローしないでください。

どんな助けでも大歓迎です。

4

4 に答える 4

3

簡単な答え: いいえ。Process のjavadocsに従って、

一部のネイティブ プラットフォームでは、標準の入力ストリームと出力ストリームに対して限られたバッファー サイズしか提供されないため、サブプロセスの入力ストリームの書き込みまたは出力ストリームの読み取りが迅速に行われないと、サブプロセスがブロックされ、デッドロックすることさえあります。

したがって、プログラムをリモートで堅牢にする場合は、stderr と stdout の処理に注意する必要があります。

そうは言っても、それらのコンテンツを本当に気にしない場合 (これは悪い考えです。破棄する有用なエラー メッセージでバッチが失敗した場合はどうなりますか?)、次のように、スレッドを起動してそれらから読み取ることができます。Jay R.の答え。これにより、ストリームの状態を気にせずにロジック スレッドを続行でき、ストリーム イーターはストリームが使い果たされるまでバックグラウンドで実行されます。Runtime.exec()これを頻繁に行う場合は、これを実行するためにスレッドを起動するラッパーを作成することもできます。

ただし、コードで解釈しない場合は、少なくともバッチ プロセスからの出力をログに記録します。バッチに問題が発生した場合、プロセスの出力を確認することで、問題の分析がはるかに簡単になります。

于 2010-08-12T16:53:43.747 に答える
2

少なくとも stdout と stderr を食べないと、最終的にメモリ不足になることがわかりました。また、複数のプロセスを同時に実行することもできませんでした。

これを行うために、ProcessStreamEater という名前のクラスを使用しています。

public class ProcessStreamEater implements Runnable
{
   private final Process proc;

   public ProcessStreamEater(Process proc)
   {
      this.proc = proc;
   }

   @Override
   public void run()
   {
      InputStreamReader r = new InputStreamReader(proc.getInputStream());
      try
      {
         while(r.read() != -1)
         {  // put stuff here if you want to do something with output
            // otherwise, empty
         }
      }
      catch(IOException e)
      {
         // handle IO exception
      }
      finally
      {
         if(r != null)
         {
            try
            {
               r.close();
            }
            catch(IOException c)
            {}
         }
      }
   }
}

それを使って物を食べると…

   ProcessBuilder pb = new ProcessBuilder(args);
   pb.redirectErrorStream(true);
   final Process proc = pb.start();
   executorService.execute(new ProcessStreamEater(proc));

executorService がExecutors.newCachedThreadPool ()で作成された場所

于 2010-08-12T16:43:02.577 に答える
0

私はあなたがこれだけを必要とすると思います:

Runtime run = Runtime.getRuntime();  
Process p = null;  
String cmd = "D:\\a.bat";     
try {     
  p = run.exec(cmd);
}catch(Exception e){
  //do handling
}

//コード

コードの後半でp.destroy()を呼び出すことを忘れないでください。上記のコードを別のスレッドで生成することもできます。お役に立てれば。

于 2010-08-12T16:18:05.787 に答える
0

プロセスがstdoutまたはstderrorへの出力を生成しない場合は、おそらくそれを処理する必要はありません。サブプロセスが出力を生成する場合、stdoutに書き込もうとしている間、永久にブロックされる可能性があります。これは、OSがバッファリングする量によって異なりますここのどこかにストリームフラッシャーの例があります-誰もが使用しています。

于 2010-08-12T16:37:28.407 に答える