System.in System.out System.err
in、out、err のストリームは、ほとんどのプログラムで使われるので、
コンパイル時に自動的にインポートされるパッケージ java.lang の System
クラスにありますが、
他の I/O 関連のものはパッケージ io にあるので、
明示的にインポートしなければなりません。
import java.io.*;
基本型の出力は、以下のように書きます。
System.out.println("Value of int "+i);
この引数には、ほとんどどんなものでもかけます。 PrintStream クラスの println メソッドは、 ふつう引数を String に変えて出力します。
java の I/O は、データの流れであるストリーム
(stream)
という概念に基づいています。
たとえばファイルシステムのファイルは、
これをプログラムに流れこませたり、
プログラムから流れ出させたりするために、
ストリームオブジェクトを使います。
ストリームオブジェクトは、インスタンシエイトするとすぐに I/O で使えます。
ストリームはデバイス独立です。
またストリームは一方向にしか流れません。あるストリームから読むことも、 あるストリームに書くこともできますが、読み書きしたい場合は、 2つの別のストリームを使わなければなりません。
java の I/O パッケージは java.ioにあり、 これらを使うためには、 このパッケージを明示的に import する必要があります。
FileInputStream | ファイルからバイト列を取得する |
StrinBufferInputStream | StrinBuffer からバイト列を取得する |
ByteArrayInputStream | byte の配列からバイト列を取得する |
PipedInputStream | パイプからバイト列を取得する |
Reader | 文字ストリームから文字列を取得する |
import java.io.*; public class read { public static void main(String argv[]) { try { FileInputStream f = new FileInputStream("read.java"); int b; while((b=f.read()) != -1) { System.out.print((char) b); } System.out.flush(); } catch (IOException e) { e.printStackTrace(); } } }
上記のプログラムを作って実行してみましょう。 |
FileOutputStream | バイト列をファイルに書き出す |
ByteArrayOutputStream | バイト列を一時的な内部領域に書き出す |
PipedOutputStream | バイト列をパイプに書き出す |
Writer | 文字列をストリームに書き出す |
出力用クラスは、すでに見た入力用クラスの反対で、read()メソッドの代わりに、 write() メソッドがあります。
write は、すべてブロッキング I/O なので、I/O が完了するまで戻りません。
import java.io.*; public class write { public static void main(String argv[]) { byte data[]={'w','r','i','t','e','.','j','a','v','a','\n'}; try { FileOutputStream f = new FileOutputStream(argv[0]); f.write(data); f.close(); } catch (IOException e) { e.printStackTrace();} } }
上記のプログラムを作って実行してみましょう。 |
File クラスには、ファイルやディレクトリに関する情報を提供する、 たくさんのメソッドがあります。
機能 | コンストラクタとメソッド |
---|---|
コンストラクタ | public File(String path) |
public File(String path,String name) | |
public File(File dir,String name) | |
ファイルの削除 | public boolean delete() |
ファイル名関連 | public String getName() |
public String getPath() | |
public String getAbsolutePath() | |
public String getCanonicalPath() | |
public String getParent() | |
public boolean renameTo(File dest) | |
ファイル属性の取得 | public boolean exists() |
public boolean canWrite() | |
public boolean canRead() | |
public boolean isFile() | |
public native boolean isAbsolute() | |
public long lastModified() | |
public long length() | |
public boolean equals(Object obj) | |
ディレクトリ関連 | public boolean mkdir() |
public String[] list() | |
public String[] list(FilenameFilter filter) | |
その他 | public static final char pathSeparatorChar |
public int hashCode() | |
public String toString() |
java Core API の java.io の File を見てみましょう。 |
ストリームを他のストリーム上にプッシュし、 フィルタ処理させることもできます。
DataInputStream | すべての基本形のバイナリ形式を読みこむ方法を与える |
BufferReader | 文字型入力ストリームから読みこむ方法を与える |
BufferedInputStream | 入力のバッファリングをサポートする |
LineNumberInputStream | 読みこまれた行数を覚えておくメソッドを提供する |
PushbackInputStream | 一度読みこんだ文字を入力ストリームに戻し、 次に読めるようにする機能を提供する |
java.io パッケージには、以下の基本的なフィルタ付き出力ストリームがあります。
PrintStream | すべての基本形を印刷可能な形式で出力する方法を与える このオブジェクトによる出力は synchronized である。 |
PrintWriter | すべての基本形を印刷可能な形式で出力する方法を与える このオブジェクトによる出力は synchronized である。 |
DataOutputStream | すべての基本形をバイナリ形式で出力する方法を与える |
BufferedOutputStream | 出力のバッファリングをサポートする |
import java.io.*; public class write2 { public static void main(String argv[]) { try { FileOutputStream f = new FileOutputStream( argv[0] ); PrintWriter p = new PrintWriter( f ); float fl = 3.1415f; p.println( "your float value is: " + fl ); p.close(); } catch(IOException ioe) {} } }
説明 | このようにすると、float や boolean や int などの型も、Unicode ファイルに 書きこむことができます。PrintWriter を使わないで FileOutputStream で float の値を書くとバイナリで書き出されます。 |
上記のプログラムを作って実行してみましょう。 |
フィルタとは、標準入力から読みこみ、何らかの変換を行い、 結果を標準出力に書くようなソフトウェアのことです。
次の例は、入力ファィル中のすべての+文字を改行に変換するフィルタです。
import java.io.*; public class filt { public static void main(String args[]) { FileInputStream fis=null; try { fis = new FileInputStream("example.txt"); } catch(FileNotFoundException fnf){ System.out.println(fnf); } Censor c = new Censor((OutputStream)System.out, (int)'+', (int)'\n'); int i=0; try { while( (i=fis.read() )!= -1 ) c.write(i); } catch(IOException ioe){System.err.println(ioe); } } } class Censor extends FilterOutputStream { int saved_remove=0; int saved_replace=0; OutputStream saved_out=out; Censor(OutputStream out, int remove, int replace) { super(out); saved_remove=remove; saved_replace=replace; } public void write(int b) throws IOException { if (b==saved_remove) b=saved_replace; saved_out.write(b); } }
JDK(Java Destribution Kit) 1.1 から、 InputStream/OutputStream に加えて、 Reader と Writer に関するクラスが追加されました。 InputStream/OutputStream が基本的に byte の入出力を行うのに対して、 Reader/Writer は char の入出力を行い、 java の内部コードである Unicode を扱います。
InputStream/OutputStream が OS などの下位のレイヤに直接アクセスするのに対して、 Reader/Writer は InputStream/OutputStream を介してアクセスします。 このように分離した目的は、国際化のためです。
InputStream/OutputStream が対象とする byte ストリームは、 OS に依存したエンコーディングが行われます。 他方 Reader/Writer が扱う char ストリームでのエンコーディングは、 Unicode であることを保証します。 このようにレイヤに分離することで、 上位のレイヤでは下位のレイヤのコーディングを意識する必要がなくなります。
コード変換には ByteToCharConverter と CharToByteConverter が使われています。 システムプロパティや環境を参照して、適切なコンバータクラスを使って変換します。 もちろん EUC、シフト JIS、JIS などに対応したクラスもあります。
注意 |
DataInputStream はバイナリデータを読みこむクラスのため、
このクラスにあるメソッド readLine() が deprecated(非難される)になりました。
このメソッドを含むプログラムをコンパイルすると以下のような警告が出ます。
> javac test.java 注意: test.java は推奨されない API を使用しています。 詳細については、"javac -deprecation" コマンドを使用してください。 警告 1個 DataInputStream はバイナリデータを読みこむクラスなので、 行のようにテキストデータでしか定義できない概念を含むものは取り除かれました。 このかわりに BufferedReader の readLine() を使えます。 そのためには、バイトストリームを文字ストリームに変換する InputStreamReader を仲介者として使います。
static DataInputStream dis = new DataInputStream(System.in); ==> static BufferedReader dis = new BufferedReader( new InputStreamReader(System.in);
|
基本 I/O に関する例外についてまとめます。
FileNotFoundException | 指定したファイルがなかった |
InterrupedIOException | I/O の途中で割り込みがあった |
UTFDataFormatException | 間違った UTF-8 コードがある |
EOFException | プログラマが指定した量の入力を読み終わる前に、 ファイルが終わってしまった場合に生じるもので、 通常の状態で end of file に遭遇しても、この例外は発生しない。 |
java からプログラムを実行するには、次の3つのステップが必要です。
import java.io.*; public class Who { public static void main(String args[]) { int ret; try { Runtime rt = Runtime.getRuntime(); // step 1 Process prcs = rt.exec("/bin/who"); // step 2 BufferedReader d = new BufferedReader( new InputStreamReader(prcs.getInputStream())); // step 3. BufferedReader e = new BufferedReader( new InputStreamReader(prcs.getErrorStream())); // step 3. String line; while ((line = d.readLine()) != null) System.out.println(line); while ((line = e.readLine()) != null) System.out.println(line); ret = prcs.exitValue(); // get exit code prcs.destroy(); // stop /bin/who System.exit(ret); } catch(IOException ioe) { System.out.println(ioe); } } }
上記のプログラムを作って実行してみましょう。 |
java.io クラスのまとめ |
java.io にあるクラスとインタフェースについてまとめました。
インタフェース | 抽象クラス | クラス | と色分けしました。 |
カテゴリ | バイトストリーム | 文字型ストリーム | 分 類 |
---|---|---|---|
基本系 | InputStream | Reader | ストリーム入出力の抽象クラス |
OutputStream | Writer | ||
DataInput | データ入出力インタフェース | ||
DataOutput | |||
ObjectInput | オブジェクト入出力インタフェース | ||
ObjectOutput | |||
FilterInputStream | FilterReader | フィルタ入出力クラス | |
FilterOutputStream | FilterWriter | ||
生成系 | FileInputStream | FileReader | ファイル入出力クラス |
FileOutputStream | FileWriter | ||
ByteArrayInputStream | CharArrayReader | 配列入出力クラス | |
ByteArrayOutputStream | CharArrayWriter | ||
InputStreamReader | バイトストリームを文字型ストリームに変換するクラス | ||
OutputStreamWriter | |||
PipedInputStream | PipedReader | パイプ入出力クラス | |
PipedOutputStream | PipedWriter | ||
SequenceInputStream | シーケンス入力クラス | ||
StringReader | 文字列入出力クラス | ||
StringWriter | |||
付加 機能 |
DataInputStream | ストリーム入出力クラス | |
DataOutputStream | |||
ObjectInputStream | オブジェクト入出力クラス | ||
ObjectOutputStream | |||
BufferedInputStream | BufferedReader | バッファ入出力クラス | |
BufferedOutputStream | BufferedWriter | ||
LineNumberReader | 行入力クラス | ||
PrintStream | PrintWriter | コンソール出力クラス | |
PushbackInputStream | PushbackReader | プッシュバック入力クラス |
ストリームは java.io に定義されている以下のクラスが基礎になっています。
種類 | クラス | 分 類 |
---|---|---|
直列化 | Serializable | 直列化宣言インタフェース |
Externalizable | 外部化宣言インタフェース | |
ObjectInputValidation | オブジェクト検証コールバックインタフェース | |
ObjectStreamClass | 直列化オブジェクト管理クラス | |
ファイル | File | ファイルクラス |
FileDescriptor | ファイル記述子クラス | |
FilenameFilter | ファイル選択インタフェース | |
RandomAccessFile | ランダムアクセスクラス | |
その他 | StreamTokenizer | トークン解析クラス |