[ Top ] > [ Communication ] > [ study ] > [ Java ]
>Stream-1-
a
 
 

Stream-1-

おそらく、Javaを初めて突き当たる問題の一つが「 stream 」じゃないでしょうか。
私も、さっぱり意味がわかりませんでした。
そういえば、Perl を勉強し始めたときに同じように、よくわからない曖昧なものに ファイルポインタ がありました。(Perlではファイルハンドルでしたっけ?)
ファイルをオープンすると、それによって出来たファイルポインタを使ってやりとりする。
そんな感じの説明を受けたように思います。

今回のこの ストリーム も、おそらくそんな感じのものだと思います。

大事なのは、「慣れ」かもしれません。
そこでなれるために、簡単なストリームを使ったプログラムを作りました。

> keyboardInAndOut.java

import java.io.*;

class keyboardInAndOut{
 public static void main(String args[ ]){
  String s = null;
  String end = "end";

  while(true){
   try{
    InputStreamReader i = new InputStreamReader(System.in);
    BufferedReader bf = new BufferedReader(i);
   s = bf.readLine( );
   if ( s.equalsIgnoreCase( end ) )
    break;
  }catch( Exception e ){
   System.out.println("キーボードからの受付失敗");
   System.exit(1);
  }
  System.out.println( s );
  }
 }
}

なんか、短く済ませようかと思ってたんですけど、長いですね。(; ̄ー ̄A

えっと、
String s = null;
にしたのは、じゃないとコンパイルするときに初期化されてませんよ〜。って注意してくるからです。
null をいれてあげたらおとなしくなりました。^ ^;
Streng end = "end";
となっているのは、キーボードから「 end 」という文字列が来たら終了させるためです。
でも、「ctrl + C」でも終了できるので。えぇ。

InputStreamReader i = new InputStreamReader(System.in);
入力ストリームを作成するときは、InputStreamReaderクラスをインスタンス化し、引数として入力元(ここでは System.in)を渡すそうです。
文字データを扱うクラスは、Reader、Writerというクラスがありますが、これは抽象クラス、つまり、インスタンス化できない継承されることが前提のクラスなので、それを継承したInputSteamReader、OutputStreamWriterクラスを使用します。他にもBufferedWriterクラスなどがサブクラスとしてあるようです。

BufferedReader bf = new BufferedReader(i);
エンターキーを押すまでを扱うには、BufferedReaderクラスを使います。引数に今インスタンス化させた i を渡します。これについては、ここを。

s = bf.readLine( );
今作成したBufferedReaderクラスのreadLineメソッドは一行読み込んで、読み込んだ値を返します。

if ( s.equalsIgnoreCase( end ) )
 break;
えっと、もし end に格納させている文字列と同じ文字列が来たら while を抜け出して終了します。また、大文字小文字区別なく文字列が同じかどうかを確認するには、Stringクラスのメソッドである equalsIgnoreCase を使用します。間違っても、今までの癖で
if ( s == end )
とはしないでください。

catch( Exception e ){
でました。try catch。 今までここは、
catch( Exception )
と、やっていました。これでも間違いじゃぁありません。で、今回は・・・
Exception にしています(同じじゃん (^ ^ ;ゞ)。んと、これはまたここで説明します。

System.out.println( s );
受け取った文字列を出力します。

はぁ。やっと終わった・・・。あ、いや、まだ終わってません。えっと、今回は、
BuffereReaderクラスを使いましたが、1行じゃなくて1文字だったらどうなるんだろう。と、思い、以下のように直しました。

import java.io.*;

class keyboardInAndOut{

 public static void main(String args[ ]){
  int c = '\0';
  InputStreamReader i = new InputStreamReader(System.in);
  while(true){
   try{
    c = i.read();
   }catch(Exception e){
    System.out.println("キーボードからの受付失敗");
    System.exit(1);
   }
   System.out.print((char)c);
  }
 }
}

えっと、実はこれ、1文字打つごとに文字を返してくるつもりでやったんですけど・・・。うまくいきませんでした。(^ ^ ;ゞ
たぶん、このプログラムが悪いのではなくて、コマンドで打ってもバッファでためてエンターで送るような仕組みなのだと思います。
で、これでも最初の方のプログラムと同じ動作をします。

int c = '\0';
えー。今回は1文字1文字について動作するようにさせたいので、int型の変数を用意しました。
最初の方と同じように、
int c;
だと、初期化されていないかも。と、注意されたので。
\0 は、C言語で文字列の終わりを示す文字なので・・・。何となく・・・。

InputStreamReader i = new InputStreamReader(System.in);
これ。これ自体ですでにキーボードから受け付けますよ。という事みたいですね。

c = i.read();
同じように、InputStreamReaderクラスのメソッドだけで取り出せます。
今回は、 readLine が使えませんので。あ、使いませんので。かな。

catch(Exception e)
ここは、Exception が、すべての例外のスーパークラスとなりますので、ここに
Exceptionクラスにしておけば、必ず例外が起こったときキャッチしてくれます。
つまり、 runtimeExceptionクラスやIOExceptionクラスは、Exceptionクラスのサブクラスとなります。ほんで、ここをExceptionクラスにしておけば、 e に、どんな例外かが入ってるのですが・・・。

System.out.print((char)c);
ここで、 charにキャスティングしておかないと、文字コードのまま出力されます。
つまり、文字一つではなく数字として扱われます。