標準入出力


高度な出力操作

おそらく、多くのJava言語の解説書では最初に入出力の本質は教えません
javaでは、深いコアクラスの理解がなければ入出力を本質的に操作できないのです
そのため、通常は「Systen.out.println() と書けば画面に文字が出せます」というような説明だけです

では、ここでJavaの入出力について触れてみたいと思います
データの入出力は、実は画面に送るのもファイルに送るのも同じです
ようはストリームがどこを指しているかであって、System.out.println()は標準出力ストリームを指しているにすぎません

println()メソッドは、改行文字を付属してストリームに文字列を書き込むメソッドです
このメソッドはjava.io.PrintStreamクラスで定義されています
PrintStreamクラスはプラットフォームのデフォルトの文字符号化を使用しバイトに変換して、出力ストリームに出力するクラスです
コンストラクタはJDK1.1以降で推奨されないので紹介しません
print()とprintln()について、ここで調べてみましょう

public void print(type)
public void println(type)

typeには boolean , char , char[] , int , long , float , double , Object , String を渡せます
println()はパラメータを省略でき、省略時は改行文字を出力します
私たちはこれまで、結果を画面に出力するのにこのメソッドを使っていました

では、先頭のSystem.outとはなんでしょう?
これはjava.lang.Systemクラス定数です

public static final PrintStream out
public static final PrintStream err

これらは、すでに開かれている標準出力と標準エラー出力へのストリームです
Systemクラスには、これらがPrintStreamクラスのオブジェクトの定数として定義されているのです
class test {
        public static void main(String args[]) {
                System.out.println("Kitty on your lap");
                System.err.println("Kitty on your lap");
        }
}
一方は標準出力なので、リダイレクトすると標準エラー出力のみが出力されます

ファイルに書き込むには新しい別のストリームを指定する必要があります
ですがPrintStreamクラスは推奨されないのでjava.io.PrintWriterクラスを利用します

public PrintWriter( Writer out )
public PrintWriter( Writer out, boolean autoFlush )
public PrintWriter( OutputStream out )
public PrintWriter( OutputStream out, boolean autoFlush )

Writerクラスはjava.io.FileWriterなどのスーパークラスです
java.io.OutputStreamは、バイトストリームの抽象クラスです
PrintStreamクラスなどのスーパークラスにあたります

autoFlushをtrueにすると、println()のたびに自動的にフラッシュされます
falseか省略した場合はフラッシュされません

PrintWriterクラスはPrintStreamクラスに変わるクラスなので
メソッドはprint()やprintln()など、PrintWriterクラスと変わらないと思ってかまいません
これで、使いなれたPrintln()メソッドなどを用いてファイルの入出力ができるのです
import java.io.*;

class test {
        public static void main(String args[]) {
                try {
                        FileWriter pass = new FileWriter(args[0]);
                        PrintWriter fp = new PrintWriter(pass);
                        fp.println("Kitty on your lap");
                        fp.println("CardCaptorSakura");
                        fp.close();
                }
                catch (IOException err) {
                        System.out.println(err);
                }
                catch (ArrayIndexOutOfBoundsException err) {
                        System.out.println("使い方 : java test <ファイル名>");
                }
        }
}
また、次のように標準出力を割り当てることもできます
import java.io.*;

class test {
        public static void main(String args[]) {
                PrintWriter fp = new PrintWriter(System.out);
                fp.println("Kitty on your lap");
                fp.println("CardCaptorSakura");
                fp.close();
        }
}
System.outはPrintStreamのオブジェクトであり、標準出力ストリームを開いています
PrintStreamクラスはOutputStreamクラスを拡張しているので、PrintWriterのコンストラクタに渡せます


標準入力を使用する

これまでは、何らかの入力にはコマンドラインを利用してきました
しかし、実用的なコンソールアプリケーションを作成する場合はそれだけではいけませんね

やはり、キーボードから文字を入力させる機能がほしいです
そうすれば、常にユーザーと対話しながら処理を進めることができます

JavaのIOは非常に汎用的で(それが、逆に欠点でもあるが)
キーボードからの入力といっても、様々なアプローチが考えられます
(この点は、C言語とは大きく違うJavaの特徴の一つだと思う)

まず、最初に利用するのはSystemクラスのSystem.inです

public static final InputStream in

これは、標準入力へのストリームを開いている定数ですが
ここで新しいクラスjava.io.InputStreamが出てきました
この抽象クラスは、バイトの入力ストリームを表すすべてのクラスのスーパークラスです

アプローチの一つの方法として、一般的なのはjava.io.InputStreamReaderクラスを利用することでしょう
このクラスはReaderクラスを拡張しているので、InputStream下のクラスではありませんが
コンストラクタからInputStreamのオブジェクトを受け取れます

public InputStreamReader( InputStream in )
public InputStreamReader( InputStream in, String enc ) throws UnsupportedEncodingException

encは使用する文字符号化名を指定します
このクラスは、read()メソッドを実装しているのでこれを利用することができます
通常、コンソールからの入力は一行なのでこの場では改行コードをキーワードに終了させましょう
import java.io.*;

class test {
        public static void main(String args[]) {
                int i = 0;
                System.out.print("何か入力してください>");
                try {
                        InputStreamReader fp = new InputStreamReader(System.in);

                        while(true) {
                                i = fp.read();
                                if (i == '\n') break;
                                System.out.print((char)i);
                        }
                        fp.close();
                }
                catch (IOException err) {
                        System.out.println(err);
                }
        }
}
より汎用的にする場合はBufferedReaderクラスのreadLine()メソッドなどを使うと良いですね
どのクラスのなんのメソッドを使用するか、様々な選択があります



前のページへ戻る次のページへ