- PR -

BufferedReaderのreadLineについて

投稿者投稿内容
SUNNYDAY
常連さん
会議室デビュー日: 2004/07/14
投稿数: 49
投稿日時: 2005-05-04 16:04
こんにちわ。
いつもお世話になっております。

BufferedReaderについて質問なのですが、
Runtime#execで起動したコマンドの出力結果を
readLineで常に最新行を読み込んで、
クラスのメンバに保存しておきたいのです。
タイマークラス等を使わないとできないでしょうか?
良い方法をご存知の方ご教授願います。m(_ _)m
SUNNYDAY
常連さん
会議室デビュー日: 2004/07/14
投稿数: 49
投稿日時: 2005-05-04 16:19
自己レスです。
スレッドを使ったらどうかなと思いました。

class クラス extends Thread {

private static BufferedReader reader;
private static Process proc;
private static volatile String line="";

メソッドA {
  proc=Runtime.getRuntime().exec(command);
reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
}

public void run() {
  try {
  while(reader.ready())
   vmstatLine=reader.readLine();
 }catch(IOException e){
  throw new RuntimeException(e);
 }
}

こんな感じでしょうか・・・?
ykhr
会議室デビュー日: 2004/11/12
投稿数: 18
投稿日時: 2005-05-04 19:55
単に、
引用:
Runtime#execで起動したコマンドの出力結果を
readLineで常に最新行を読み込んで、
クラスのメンバに保存しておきたいのです。


というのであれば、ThreadクラスとかTimerクラスはまったく関係いと思うのですが?
普通に実装した場合に、何か問題でもあるのでしょうか?

それとも、すでにRuntime#execをやっているThreadを継承したクラスがあって
その最終行を保持しておきたいということでしょうか?
aa
ぬし
会議室デビュー日: 2004/01/08
投稿数: 299
投稿日時: 2005-05-04 20:31
シンプルな例としては、こんな感じです。
コード:
try {
  proc = Runtime.getRuntime().exec(command);
  reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));

  while (null != (line = reader.readLine()) {
    //ここに処理書く
  }

} catch (IOException e) {
  //ここにエラー処理書く

} finally {
  try {
    reader.close();
  } catch (IOException e) {}
}


SUNNYDAY
常連さん
会議室デビュー日: 2004/07/14
投稿数: 49
投稿日時: 2005-05-05 17:48
引用:

未記入Yさんの書き込み (2005-05-04 19:55) より:
単に、
引用:
Runtime#execで起動したコマンドの出力結果を
readLineで常に最新行を読み込んで、
クラスのメンバに保存しておきたいのです。


というのであれば、ThreadクラスとかTimerクラスはまったく関係いと思うのですが?
普通に実装した場合に、何か問題でもあるのでしょうか?

それとも、すでにRuntime#execをやっているThreadを継承したクラスがあって
その最終行を保持しておきたいということでしょうか?



未記入Yさん、aaさんご回答ありがとうございました。
スレッド等を使わなくても、最新行を常にメンバに設定できるのですか!?
え〜っと、サンプルの例をみると、
コマンドを実行した瞬間の最新行は取得できると思うのですが、
この記述で、その後も常に最新行って取得できるのでしょうか・・・?
トーキー
会議室デビュー日: 2004/11/19
投稿数: 6
投稿日時: 2005-05-05 19:58
SUNNYDAYさん こんにちは。

BufferedReaderクラスを使用する事が必須でないのであれば、
FileOutputStreamクラスを使えば、第2引数にtrueを渡す事で、
ファイルの最終行に追記できますよ。

↓SunのJavadoc
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/FileOutputStream.html

aa
ぬし
会議室デビュー日: 2004/01/08
投稿数: 299
投稿日時: 2005-05-06 21:00
トーキーさんのは、ファイルに書き出したいときの話ですよね。

それより、そもそもSUNNYDAYさんの「最新行」というのが、
どういう意味で使われているのか分かりかねるのですけど。

processを実行して標準出力とかエラー出力とかが大量に出力
されるとしても、あくまで最後の1行だけ読みたい(それ以
外は決して読みたくない)という意味ですかね?
プロセスが実行中なら現実的に不可能な事は分かってますよね?
だって本当に最後かどうか誰も分かりませんから。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2005-05-06 22:21
引用:

aaさんの書き込み (2005-05-06 21:00) より:
processを実行して標準出力とかエラー出力とかが大量に出力
されるとしても、あくまで最後の1行だけ読みたい(それ以
外は決して読みたくない)という意味ですかね?
プロセスが実行中なら現実的に不可能な事は分かってますよね?
だって本当に最後かどうか誰も分かりませんから。


「任意のその時点での最新」ならいいのではないですか ? つまり次々読み捨ててかまわない、と。

で本題ですが、「最新行を読んでは保存する」スレッドを作った方がいいでしょうね。ただ、
コード:
while(reader.ready())
   vmstatLine=reader.readLine();


だと最初に ready() が false を返したとき(今のところ最新の行を取り尽くしたとき)にスレッドが終わってしまうのでさらにループで囲った方がいいでしょうね。
おそらくループを回しっぱなしにすることによる負荷を気にしておられるのかもしれませんが、そのときは適当に Thread.sleep() か wait() を入れてみるといいかもしれません。
コード:
try{
  while(true){
    while(!reader.ready()){
      Thread.sleep(待ち時間);
    }
    synchronized(vmstatLine){ // ほかにもロックが必要かもしれませんけど
      vmstatLine = reader.readLine();
    }
  }
}catch(InperuptedException ie){
  // スレッドが割り込まれたときの処理
}catch(IOException ioe){
  // IOException が発生したときの処理
}

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