質問
ようにしている実行プロセスという、その入力、出力とエラーフレームワークの方法がこれを行うためのものを使っておけば間違いないように select()
, が、この中で見らJavaとなる Selector.select()
, 人間の Channel
.でなにが可能です Channel
から InputStream
または OutputStream
(FileStream
は getChannel()
方法がいがこちら)
なので、代わりに書いた一部のコードをポーリングすべてのストリームに分類されます。
while( !out_eof || !err_eof )
{
while( out_str.available() )
{
if( (bytes = out_str.read(buf)) != -1 )
{
// Do something with output stream
}
else
out_eof = true;
}
while( err_str.available() )
{
if( (bytes = err_str.read(buf)) != -1 )
{
// Do something with error stream
}
else
err_eof = true;
}
sleep(100);
}
ることを除いて、で終了します。時の流れがファイルの終わり, available()
ゼロを返しまう read()
なれませんので、-1を返しすることを示しますEOF.
ついにより、非ブロックを検出EOF.見えないことに気づいたのdocsます。あるいはあるものって何をしたいのか?
私はこの質問はこちらリンクテキストをドキュメント はなそういう思いだけでなく、使うのは、産卵に別のスレッドごとのストリームのために特に問題にしています。が確実にそうではないだけないというのですか?確実な方からの読み込み複数のストリームを使用せずにスレッドのために?
解決
になっているということで、液 この答え の伝統的な読みの両方を標準出力に出力およびstderrからです。スレッド-per-ストリームはもはやや迷惑なレベルまでさまざまです。
他のヒント
でそれを行ってみてはいかがでしょうルートの産卵のスレッド毎にストリームにしたい。ご利用の場合を可能に合わせて標準出力に出力およびstderrのプロセスの質問に必要な唯一のスレッド、それ以外は必要です。
もあり得るかもしれないですつのプロジェクトがうれしい打上げに外部プロセス、その出力といいながら同時に見るエラー処理終了までに終了ときには、javaアプリのユーザーを解除したときは動作します。
作成した比較的単純なクラス封止の観部のrun()メソッドをするとどうなるのかわかりません
public void run() {
BufferedReader tStreamReader = null;
try {
while (externalCommand == null && !shouldHalt) {
logger.warning("ExtProcMonitor("
+ (watchStdErr ? "err" : "out")
+ ") Sleeping until external command is found");
Thread.sleep(500);
}
if (externalCommand == null) {
return;
}
tStreamReader =
new BufferedReader(new InputStreamReader(watchStdErr ? externalCommand.getErrorStream()
: externalCommand.getInputStream()));
String tLine;
while ((tLine = tStreamReader.readLine()) != null) {
logger.severe(tLine);
if (filter != null) {
if (filter.matches(tLine)) {
informFilterListeners(tLine);
return;
}
}
}
} catch (IOException e) {
logger.logExceptionMessage(e, "IOException stderr");
} catch (InterruptedException e) {
logger.logExceptionMessage(e, "InterruptedException waiting for external process");
} finally {
if (tStreamReader != null) {
try {
tStreamReader.close();
} catch (IOException e) {
// ignore
}
}
}
}
呼び出し側では以下のようなものです:
Thread tExtMonitorThread = new Thread(new Runnable() {
public void run() {
try {
while (externalCommand == null) {
getLogger().warning("Monitor: Sleeping until external command is found");
Thread.sleep(500);
if (isStopRequested()) {
getLogger()
.warning("Terminating external process on user request");
if (externalCommand != null) {
externalCommand.destroy();
}
return;
}
}
int tReturnCode = externalCommand.waitFor();
getLogger().warning("External command exited with code " + tReturnCode);
} catch (InterruptedException e) {
getLogger().logExceptionMessage(e, "Interrupted while waiting for external command to exit");
}
}
}, "ExtCommandWaiter");
ExternalProcessOutputHandlerThread tExtErrThread =
new ExternalProcessOutputHandlerThread("ExtCommandStdErr", getLogger(), true);
ExternalProcessOutputHandlerThread tExtOutThread =
new ExternalProcessOutputHandlerThread("ExtCommandStdOut", getLogger(), true);
tExtMonitorThread.start();
tExtOutThread.start();
tExtErrThread.start();
tExtErrThread.setFilter(new FilterFunctor() {
public boolean matches(Object o) {
String tLine = (String)o;
return tLine.indexOf("Error") > -1;
}
});
FilterListener tListener = new FilterListener() {
private boolean abortFlag = false;
public boolean shouldAbort() {
return abortFlag;
}
public void matched(String aLine) {
abortFlag = abortFlag || (aLine.indexOf("Error") > -1);
}
};
tExtErrThread.addFilterListener(tListener);
externalCommand = new ProcessBuilder(aCommand).start();
tExtErrThread.setProcess(externalCommand);
try {
tExtMonitorThread.join();
tExtErrThread.join();
tExtOutThread.join();
} catch (InterruptedException e) {
// when this happens try to bring the external process down
getLogger().severe("Aborted because auf InterruptedException.");
getLogger().severe("Killing external command...");
externalCommand.destroy();
getLogger().severe("External command killed.");
externalCommand = null;
return -42;
}
int tRetVal = tListener.shouldAbort() ? -44 : externalCommand.exitValue();
externalCommand = null;
try {
getLogger().warning("command exit code: " + tRetVal);
} catch (IllegalThreadStateException ex) {
getLogger().warning("command exit code: unknown");
}
return tRetVal;
残念なことになって自含まれるrunnableの例では、もっこりませんでした。またいでいいを見直すということをねじになります。interrupt()メソッドの代わりに無停止フラグ(こころ-からだ-いのちを宣言するので揮発!), だるます。:)