Javaのストリーム

しばらく触ってないとすっかり忘れてしまうので、まとめておく。

Javaでは、まず文字とバイト列を別々に扱う。その中で、欲しい機能によってオブジェクトを組み合わせて使う。例えばFileReader + BufferedReader みたいな。
なんでI/Oごときにこれほどたくさんの種類のクラスを使い分けないといけないんだ!ということで、俺はJavaのストリームが大嫌いです。
まあ、慣れなんだろうけどさ・・・。Javaを日常的に使うわけではない人にとっては、敷居高すぎだろ・・・。

  • 文字ストリーム
    • java.io.Reader
      • BufferedReader
      • InputStreamReader
        • FileReader
    • java.io.Writer
      • BufferedWriter
      • OutputStreamWriter
        • FileWriter
  • バイトストリーム
    • java.io.InputStream
      • FileInputStream
      • FilterInputStream
        • BufferedInputStream
        • DataInputStream
    • java.io.OutputStream
      • FileOutputStream
      • FilterOutputStream
        • BufferedOutputStream
        • DataOutputStream
        • PrintStream

こうしてみると、文字ストリームの java.io.Reader/Writer 系とバイトストリームの java.io.Input/OutputStream は相容れないようですが、この二つをつなぐ存在として InputStreamReader/OutputStreamReader があります。
例えばSocketクラスのgetInputStream()は入力ストリームをバイトストリームで返してきますが、これを文字列として扱いたい場合は、getInputStream()の返り値をInputStreamReaderでラップしてやればよいです。さらにBufferedReaderでラップすれば、readLine()のような便利なメソッドを使うこともできるという寸法です。

にしても

Cだったらファイルもソケットもfile descriptor1つで表せるし、UNIXレベルのVFSならvnode1つで表せるのに。何でJavaだけこんなにしちめんどくさいんだろ。思想的には分からないでもないけどさ。