Revised: Mar./16th/2002
多くの言語で、入力を別の形態に変形する仕様がサポートされています。例えば、 UNIX 系 OS の sort
, nl
, grep
などが代表的なものです。これらは、入力データを、並べ替え、行番号付け、検索の機能でフィルターして、結果を出力します。
Java では次のクラスが基本的なフィルター機能を提供します。
文字ストリーム | FilterReader FilterWriter |
---|---|
バイトストリーム | FilterInputStream FilterOutputStream |
これらのクラスは別のクラスに継承されて、各々が異なる機能を提供します。例えば、 FilterOutputStream
は次のクラスに継承されています。
BufferedOutputStream
: バッファリングされた出力ストリームCheckedOutputStream
: 書き込まれたデータのチェックサムも保持する出力ストリームDataOutputStream
: バイトストリームへ基本データ型を出力DeflaterOutputStream
: deflate 圧縮形式で圧縮されているデータの出力ストリームフィルタDigestOutputStream
: 関連したメッセージダイジェストを更新する透明なストリームPrintStream
: ほかの出力ストリームに色々な機能を追加BufferedOutputStream
や PrintStream
は何度か使いました。本稿では、その他によく使う、 DataInputStream
/DataOutputStream
を紹介します。
DataInputStream
/DataOutputStream
これらのクラスは FilterInputStream
/FilterOutputStream
を継承したクラスで、バイト型入出力のストリームで基本データ型を扱えるようにするものです。他のストリームでは、基本データ型のデータは文字列型に変換されて扱われます。
継承関係:
DataInputStream | DataOutputStream | java.lang.Object | +--java.io.InputStream | +--java.io.FilterInputStream | +--java.io.DataInputStream | java.lang.Object | +--java.io.OutputStream | +--java.io.FilterOutputStream | +--java.io.DataOutputStream |
---|
コンストラクタ:
DataInputStream(InputStream in) DataOutputStream(OutputStream out)
これらのクラスはコンストラクタ引数に InputStream
/OutputStream
型の参照を要求します。これらのクラスを継承したストリームならば全て可能と言うことです。
最初に基本データ型での出力を試してみます。出力データはソースコードの中に書き込んでいます。基本データ型が文字列に変換されること無く、そのまま出力されます。
import java.io.*; //書き込みサンプル class AddrOut { public static void main(String[] args) throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("addr.txt")); String[] names = { "NEXTindex", "Yahoo! Japan", "Google", "Amazon" }; String[] uris = { "http://www.nextindex.net/", "http://www.yahoo.co.jp/", "http://www.google.co.jp", "http://www.amazon.co.jp" }; for (byte b = 0; b < names.length; b ++) { out.writeByte(b+1); out.writeChar('\t'); out.writeUTF(names[b]); out.writeChar('\t'); out.writeUTF(uris[b]); out.writeChar('\n'); } out.close(); } }
出力用のメソッドは、データ型に応じて複数用意されています。各メソッドの詳細は API 仕様書に譲りますが、次の順番で書き込んでいます:
[バイト型][タブ][文字列][タブ][文字列][改行文字]
このファイルは、複数のデータ型が混在しているので、普通にテキストエディタで開いても適切に表示することは出来ません。
先程出力したファイルから各データを読み込んでみます。読み込み用のメソッドは、データ型ごとに用意されていますが、何れもファイル終了文字 [EOF]
(End Of File) を読み込むと EOFException
を発生させます。従って、読み込みの無限ループを作って、そこで発生したこの例外をキャッチすることでループから脱出できます。
import java.io.*; // 読み込みサンプル class AddrIn { public static void main(String[] args) throws IOException { DataInputStream in = new DataInputStream(new FileInputStream("addr.txt")); byte serial; String name; String uri; try { while (true) { serial = in.readByte(); in.readChar(); //タブ name = in.readUTF(); in.readChar(); //タブ uri = in.readUTF(); in.readChar(); //\n System.out.println(serial + ";\t" + name + ";\t" + uri); } } catch (EOFException e) { System.out.println("End of File"); } in.close(); } }
データ型ごとに別のメソッドで読み込んでいます。それらは System.out.println()
で出力していますが、Systen.out
は PrintStream
型であり、そのメソッド print()
/println()
は基本データ型を文字列に変換 (String.valueOf()
) してから出力します。
実行例:
C:\IO>javac AddrIn.java C:\IO>java AddrIn 1; NEXTindex; http://www.nextindex.net/ 2; Yahoo! Japan; http://www.yahoo.co.jp/ 3; Google; http://www.google.co.jp 4; Amazon; http://www.amazon.co.jp End of File C:\IO>