第6講:入力された「時間割」をファイルに保存する

その2 ファイル出力された「1日分の時間割」を読み込んで    内容を表示する「ClassTableReader」 を作成する

 つぎに、その1で作成した「ClassTableWriter」によって出力されたファイル「Day.data」を読み込むしくみについて学習します。といっても機構は非常にシンプルで、出力の際にたどったStream(データの流れ)の、今度はちょうど正反対をたどればいいのです。ここでは「1日分の時間割」を保存するファイル「Day.data」を読み込んで、その内容をディスプレイに表示する、「ClassTableReader」を作成してみましょう。

(1)「ClassTableReader」の設計

 今回作成する「ClassTableReader」は、「ClassTableWriter」によって作成された「1日分の時間割」が保存されたファイル(Day.data)を読み込み、その内容のすべてを1限目から順に一覧表示するものとします。これも前回と同様属性とメソッドから設計してゆきます。

 このプログラムが「ClassTableWriter」とちょうど正反対の機能を持っているということはすでにお気づきですね。ここから、属性及びメソッドとしては以下のものをあげるのが自然だと思われます。

属性1 「1日分の時間割」
 ファイルから読み込んだ「1日分の時間割」を受け取るために用意します。読み込んだデータを元の形に戻す、という考え方です。
>>記述例

メソッド1「ファイルから「1日分の時間割」を読み込むメソッド」
 このメソッドは「ClassTableWriter」の「fileOut」メソッドとちょうど正反対の働きをします。すなわち、指定されたファイルからデータを読み込み、そのデータを元々の形だったVectorのインスタンスへと戻す、ということです。従ってメソッド名は「fileIn」にしておきましょう。引数は想定しません。なお、このための記述は後ほど説明します。

メソッド2「Vectorに格納された「1日分の時間割」をディスプレイに表示するメソッド」
 このメソッドの働きは、ファイル読み込みの後にVectorに戻された「1日分の時間割」を1限目から順に表示することです。メソッド名は「print」にしておきます。
 一旦Vectorに格納された「授業の情報」を取り出して表示する、というのはすでに第5講で学習しました。ただしこのメソッドの場合は一つだけ表示するのではなく、Vectorに格納されているすべての要素を1番目(「0番」の部屋に入っている)から順に表示してゆきます。したがって、「繰り返し文」を使いながら「Vectorからの取り出し → 表示」を繰り返してゆくことになります。
 そこで、ちゃんと順番に表示するためにはちょっとした工夫が必要になります。ヒントは、「繰り返し回数をカウントする変数」と「elementAtメソッドの引数」をうまく連動させる、ということです。Vectorの要素は0番の部屋から順に格納されています。カウントも「0」から行うことができます。だからわざわざ別の変数を用意することは、、、。これでおわかりでしょうか?
 ちなみにこれも引数は想定しません。
>>記述例

メイン・メソッド
 「ClassTableWriter」と同じ要領で考えれば、「fileOut」メソッドと「print」メソッドに引数が必要ない以上、非常に簡単に書けますね。
>>記述例

(2)データのファイル入力の方法

 今度はファイル入力の方法です。先ほどの「ファイル出力」のプロセスと、全く逆のプロセスをたどればよいのです。登場するクラスは「FileInputStream」と「ObjectOutputStream」です。概念的には、以下のようになるわけです。

ファイル>-- FIS -→ >-- OIS -→ Vectorのインスタンス
 但し FIS は FileInputStream, OIS はObjectInputStream を表す。

命令の記述は以下の順番で行います。

1)FileInputStreamのインスタンス化、引数は読み込むファイルのファイル名(文字列型)です。ちなみに今回の「fileIn」メソッドにおいては、読み込むべきファイル名が「Day.data」と決まっているので、あらかじめ書き込んでおきます。

FileInputStream インスタンス名 = new FileInputStream("ファイル名");

2)ObjectInputStreamのインスタンス化、引数はFileInputStreamのインスタンス名です。

ObjectInputStream  インスタンス名 = new ObjectInputStream(FISのインスタンス名);

3)「ObjectInputStream」の「readObject」メソッドを起動する。仮にインスタンス名をoisとします。

読み込まれるインスタンスを受け取る箱の名前 
   = (受け取るインスタンスのクラス名)ois.readObject();

「readObject」によって読み込まれるデータは、もともと何らかのクラスの「インスタンス」だったものです。これを「readObject」は返値として返します。従って代入文で受け取ってやる必要があるわけです。今回受け取るのはもちろん、「1日分の時間割」の入ったVectorクラスのインスタンスです。

 その際に注意すべきなのは、右辺には必ず()内に「受け取るインスタンスのクラス名」を明記することです。この記述は、以前VectorからClassTableのインスタンスを取り出す際に経験しています。この場合も、読み込まれるデータが元々何クラスだったのかを明示的に教えてやらなければならないのです。このように、明示的に元のクラス名を示すことを一般に「キャスト」と呼びます。また、代入文の左辺では、そのデータを受け取るために、受け取るデータと一致するクラス(つまり今回はVectorクラス)の箱を用意しておきます。

 ということで、ファイルの読み込みについての解説は以上です。あとはさっそく、「ClassTableReader」を作成してみて下さい。

>>解答例のプログラム


リンク:

<全体のトップページ>

     |

<第6講のトップページ>

     |-------------------------|

<第6講・その1>       <第6講・その2>