第6講:入力された「時間割」をファイルに保存する |
その1 入力された「1日分の時間割」をファイルに出力・保存する「ClassTableWriter」を作成する |
これまでに作成した「ClassInfo」は、折角キーボードから入力した「1日分の時間割」をプログラムが実行されている間しか保持することができませんでした。できれば一度入力したデータは後々使えるように保存しておきたいものです。またデータの入力とその利用はこのシステムの場合本来別の人間が行うべきことですが、それを実現するにはデータの恒常的な保存方法を学ぶ必要があります。ということで、今回は一旦キーボードから入力された「1日分の時間割」を、ファイルとして出力し保存するする方法を学びます。 |
(1)「1日分の時間割」のファイル出力 前回までの学習によって、当初の定義通りに5つの「授業の情報」を「1日分の時間割」としてプログラム上で表現することができるようになりました。ただしコンピュータが入力された「1日分の時間割」を記憶できるのは「ClassInfo」のメインメソッドを実行している間のみで、実行が終わると同時に入力されたデータは破棄されてしまいます。プログラムを起動するごとに新たにデータの入力をしなければならないようでは、実用性のあるシステムとはいえません。 そこで今回は、キーボードから入力されVectorにまとめられた「1日分の時間割」をファイルとして出力し、コンピュータのハードディスクに記憶させる方法を学びます。このようにしておけば、後に学ぶファイルからの情報の入力によって情報の再利用を行うことが可能になります。これから先は、この出力されるファイルのことを「データファイル」と呼びます。 |
(2)データファイル作成専用クラス「ClassTableWriter」の設計 ここで一旦「ClassInfo」の設計を見直してみましょう。このプログラムには、「「1日分の時間割」の入力」(データの入力)と「希望する時限の「授業の情報」の表示」(データの利用)という二つの機能がありました。そして、事実上これらを同一人物が行うようなプログラムとなっていました。情報のファイル保存を知らない段階では致し方のないことだったのですが、本来これらの機能は別々のプログラムに分けておくべきものです。 そこで、今回から「「1日分の時間割」の入力」と「入力された情報のファイル出力」のふたつの機能からなるデータファイル作成の専用クラス「ClassTableWriter」を新たに定義・作成したいと思います。これは後に「時間割表示システム」を完成する際に、システムが扱う1週間分の「時間割」のデータファイルを作成するクラスとして拡張してゆくものの原型です。このようなクラスをもうけることで、今度はデータの利用だけを行うクラスを考えることもできるようになります。 ここでデータの入出力という観点から、従来の「ClassInfo」とこれから作成する「ClassTableWriter」の相違点を図でまとめておきます。
ということで、この「ClassTableWriter」の設計を考えてみます。このクラスは後に拡張を行う可能性があるので、すべての処理をメイン・メソッドに記述するのではなく、あらかじめ属性、メソッドを考えた上で、実行されたときの具体的な手順をあとからメイン・メソッドに記述することにします。 まずこのクラスを作成する目的ですが、これはキーボードから読み込んだ「1日分の時間割」をファイルとして出力すること、とはっきり定義しておきます。この目的からまず属性(=そのクラスを成立させるデータの項目)を考えます。すると、おそらくまず考えられるのは「1日分の時間割」です。 属性として取り上げるデータの項目は、通常、クラスを構成するメソッドのうち複数のものに関連する可能性のあるものを選びます。ある一つのメソッドが行う処理にだけ関係する(つまりクラス全体の機能に関わらない)データはとりあげません。したがってこのクラス全体に関わるものをあげるとすれば「1日分の時間割」以外にはなさそうです。 またメソッドについても今のところ「キーボードから「1日分の時間割」を読み込むメソッド」と「「1日分の時間割」をファイルとして出力するメソッド」の二つがあれば良さそうです。そしてメイン・メソッドでは、これらの属性・メソッドを用いながら実際にファイルを出力するまでの処理手順を記述します。 それでは、それぞれについてより具体的に考えてみます。これらをヒントにプログラムの記述を考えてみてください。「メソッド2」をのぞけば既知の記述で書けるはずです。
|
(4)ClassTableWriterを実行する前に(オブジェクトのシリアライズ化について) ClassTableWriterがうまく作成できたら、早速実行してみる前に一つだけしておくことがあります。 Javaでは、先ほど説明したStreamを利用してあるクラスのインスタンスを送受信(あるいは入出力)する場合、そのインスタンスは必ずシリアライズ化(直列化)可能であると定義されていなければなりません。シリアライズ化とは、一言でいえばデータを送信するための準備であるといえます。インスタンスは属性やメソッドなどに関するデータのかたまりですが、それを丸ごと「かたまり」のままOutputStreamへ送信することはできません。シリアライズ化をすることで、一旦「かたまり」を構成要素へとバラバラに分解し、一つずつ順に送信します。 シリアライズされたインスタンスがInputStream(Javaにおける入力の流れ。次の「その2」で扱います)から受信される際には、このバラバラの構成要素は元のインスタンスのかたちへと復元されます。 今回直接送受信するのはVectorクラスのインスタンスです。Vectorクラス自体はあらかじめシリアライズ化可能と定義されており、問題ありません。しかし今回の場合、Vectorのインスタンスには「授業の情報」、すなわちClassTableクラスのインスタンスが格納されています。こういった場合、ClassTableのインスタンスもシリアライズ化可能でなくてはなりません。 そこで、次の手順でClassTableをシリアライズ化可能なクラスにします。ClassTableのプログラムのクラス名を宣言する行に、以下の赤字の記述を加えて下さい。
この「implements Serializable」を加え、そのあとでClassTableをコンパイルし直せば、それだけでこのクラスはシリアライズ化可能となります。 これでやっとClassTableWriterを実行する準備が整いました。早速実行してみて下さい。 |
リンク: <全体のトップページ> | <第6講のトップページ> |-------------------------| <第6講・その1> <第6講・その2>