- PR -

外部プログラム実行時の入力待ち検出

投稿者投稿内容
ぐっち
会議室デビュー日: 2007/07/25
投稿数: 17
投稿日時: 2007-07-26 17:34
あしゅさんありがとうございます。

外部プログラムの出力を常に待って、出力がなければ入力待ちだなと判断すればいいということですね。言われてみればふつうな気がしてきました。

でも、とりあえず出力を読み込むのをどうやればいいかイマイチよく分からないのですが、InputStream#available()で読み込み可能なバイト数を取って、ImputStream#read()で読み込めばいいのしょうか?
さっき軽く試したのですが、available()の結果が0になってしまい上手く動かないのですが、どうしたらよいのでしょうか?
よく分かってなくてすみません。
どうぞよろしくお願いいたします。

public class test {
public static void main(String[] args) {
try{
Process p=Runtime.getRuntime().exec("c:\\Perl\\bin\\perl test.pl");
InputStream is=p.getInputStream();
read pe=new read(is);
Thread th=new Thread(pe);
th.start();
}catch(IOException e){
e.printStackTrace();
}
}

}
class read implements Runnable{
InputStream is;
read(InputStream is){
this.is=is;
}
public void run(){
byte[] b=new byte[1024];
while(true){
try{
int n=is.available();
if(n>0){
is.read(b, 0, n);
String s=new String(b);
System.out.println(s);
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-07-26 18:48
引用:

外部プログラムの出力を常に待って、出力がなければ入力待ちだなと判断すればいいということですね。


え?そういうことなんですか?先行入力しておいても標準入力を読む外部プロセスは困らないから入力待ちかどうかを気にせずに入力された内容は外部プロセスの標準入力に送ってしまえばよい、ということではないですか?
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-07-26 19:00
引用:

ぐっちさんの書き込み (2007-07-26 17:34) より:
でも、とりあえず出力を読み込むのをどうやればいいかイマイチよく分からないのですが、InputStream#available()で読み込み可能なバイト数を取って、ImputStream#read()で読み込めばいいのしょうか?
さっき軽く試したのですが、available()の結果が0になってしまい上手く動かないのですが、どうしたらよいのでしょうか?


すみません。間違えました。
available()が有効なのはBufferedInputStreamくらいですね。
ブロックせずに読み込むにはスレッド作る以外に無理なようです。

引用:

未記入さんの書き込み (2007-07-26 18:48) より:
引用:

外部プログラムの出力を常に待って、出力がなければ入力待ちだなと判断すればいいということですね。


え?そういうことなんですか?先行入力しておいても標準入力を読む外部プロセスは困らないから入力待ちかどうかを気にせずに入力された内容は外部プロセスの標準入力に送ってしまえばよい、ということではないですか?


実際にその通りなんですが、双方のパイプのバッファが溢れた状態で
お互いがブロックするとデッドロックになると思うので、
単純に1スレッドでやるのは危険な気がします。
ぐっち
会議室デビュー日: 2007/07/25
投稿数: 17
投稿日時: 2007-07-26 20:46
あしゅさんありがとうございます。

InputStreamではなくBufferedInputStreamにしてやってみたのですが、同じようにavailable()の値が0になってしまい、読み込む事ができませんでした。

よく分からないのですが、結局のところどうすれば出力を読み込む事ができるのでしょうか?
どうぞよろしくお願いします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-07-26 21:03
BufferedInputStreamを被せても無意味です。
available()ではどうやっても無理なので忘れて下さい。

一度read()すればバッファの残り分の長さが返るはずですが、
その際に内部でブロックする可能性のあるread()を行うので、
一切ブロックをせずに読み込めるか判定する目的には使えません。
ぐっち
会議室デビュー日: 2007/07/25
投稿数: 17
投稿日時: 2007-07-27 12:05
あしゅさんありがとうございます。

ということは、どういう風にすれば読み込めるということでしょうか?
物分りが悪くてすみません。

read()自体が入力待ちによって止まってしまってできないのですが、どういうことでしょうか?

どうぞよろしくお願いいたします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-07-27 12:59
ここは単純に解を教えて貰う場ではありません。
検索に使えるキーワードもいくつか出していますし、
スレッドを使った実装の方針も示したつもりです。

もう十分ヒントは出ているはずです。
自分で考えましょう。

具体的にどこがわからないのか質問されれば答えます。
ぐっち
会議室デビュー日: 2007/07/25
投稿数: 17
投稿日時: 2007-07-28 16:49
あしゅさんありがとうございます。

考えてみます。

そこでまた質問で申し訳ないのですが、
read()やreadLine()等はストリームが終了していないと読み込めなくて、
僕が作ったプログラムだと止まっているのだと思うのですが、
あしゅさんのおっしゃるようなスレッドを使った方法だとなぜ解決できるのでしょうか?
初心者ですみません。どうぞよろしくお願いいたします。

スキルアップ/キャリアアップ(JOB@IT)