サブゼミ第9回 実装編③ 永続化とjava.ioパッケージ
GoalとObjective Goal ・システムの永続化をオブジェクトのシリアライズを使って 実装することができるようになる。 ・java.ioパッケージに含まれる入出力のクラスを その役割を理解して使えるようになる Objective ・テキスト保存とシリアライズして保存の違いを説明できる ・java.ioの構成を簡単に説明できる ・java.ioパッケージの主要なクラスの役割を説明できる
冬休みまでの復習 コンソールで(CUIで) 自動販売機が動くようになった ユーザメニュー:1.商品を見る 2.お金を投入する 3.商品を買う 4.お金を取り出す 5.商品を取り出す 6.メインメニューに戻る 3 投入金額:500円 cola:120円:○ soda:120円:× おつり口には0円あります 商品取り出し口には0個商品があります 購入する商品名を入力してください cola colaを購入しました おつりを380円出しました
今までの自動販売機の問題点 “実行する=電源を入れる”だと考えて 自販機として不便な点を考えてみてください “実行する=電源を入れる”だと考えて 自販機として不便な点を考えてみてください ・電源を入れるたびに取扱商品を登録しなおしたり 商品を補充しなおしたりしなければならない ・スタンドアローンなので一人しか実行できない ・商品を買うと勝手におつりが出てくる ・見た目がへぼい
システムの情報を保存する システムを永続化する 電源が切られても(プログラムが終了しても) 取扱商品や商品在庫、貨幣在庫などの情報は 保存したい。 システムを永続化する
永続化の実装方法 先学期習った方法 ・テキストデータとしてファイルに保存 ・RDB 今学期新しく扱う方法 先学期習った方法 ・テキストデータとしてファイルに保存 ・RDB 今学期新しく扱う方法 オブジェクトをシリアライズしてファイルに保存する
<復習>テキストデータでファイルに保存 入力 BufferedReader br = new BufferedReader(new FileReader(“商品名1.log”)); 商品名 = br.readLine(); br.close(); 出力 PrintWriter pw=new PrintWriter(newFileWriter(“商品名1.log”)); fw.write(商品名); fw.close();
<復習>リレーショナルデータベース //DBのURLを作成する。 String url ="jdbc:interbase://etude.crew.sfc.keio.ac.jp//home/bam/jihanki.gdb"; //DBにアクセスして、コネクションを開設する。 java.sql.Connection conn = java.sql.DriverManager.getConnection( url , "sysdba" , "masterkey" ); //SQL文をデータベースに送信して、その結果(resultSet)を受け取る String sqlString = "select * from user_info"; java.sql.Statement statement = conn.createStatement(); java.sql.ResultSet rs = statement.executeQuery( sqlString );
シリアライズとは シリアライズとはオブジェクトが持つ属性の値を 展開してビット列化すること オブジェクトをファイルへ書き出すために 属性などの複雑な構造をしたデータを ファイルに保存できる形式に変換すること
シリアライズして保存<出力> 書き出す先のストリームを引数として ObjectOutputStreamのオブジェクトを生成する ObjectOutputStream 出力= new ObjectOutputStream(new FileOutputStream(…取扱商品.log)); 出力.writeObject(取扱商品); 出力.close(); オブジェクトを書き出す ストリームを閉じる
シリアライズして保存<入力> 読み込むストリームを引数として ObjectInputStreamのオブジェクトを生成する ObjectInputStream 入力= new ObjectInputStream(new FileInputStream(“…取扱商品.log”)); 取扱商品=(取扱商品型)入力.readObject(); 入力.close(); オブジェクトを読み込んでキャストして代入 ストリームを閉じる
java.io.Serializableインターフェース public class 取扱商品型 implements Serializable{ } “このクラスのオブジェクトはシリアライズ可能である” ということを宣言するためのインターフェース。 このインターフェースを実装していないと シリアライズができない。 String、HashMapなどの主要なクラスは最初から Serializableインタフェースを実装している。 ・・・
ところで・・・ BufferedReader FileReader/Writer PrintWriter java.ioパッケージ BufferedReader FileReader/Writer PrintWriter ObjectOutputStream/InputStream これらのクラスはいったいどのような役割を持っていたでしょうか?考えてみてください
ストリームの復習 さまざまな形で入出力したデータを扱いたい (ファイル、ソケット、キーボード、ディスプレイ) ストリームはさまざまな入出力を抽象化して データの流れとして扱い、 簡単にデータへのアクセスができるようにしたもの
java.ioパッケージの概念 入出力を管理するクラスを集めたライブラリ 大きく分けて二つの種類のクラスが含まれる どこからどんな形式のデータを入出力するのかを定義しているクラス ①のタイプに追加機能を付与するクラス
どんなデータを バイト列 InputStream/OutputStreamとそのサブクラス (ObjectOutputStream/InputStream以外) 例)FileInputStream、ByteArrayInputStream 文字列 Reader/Writerとそのサブクラス 例)FileReader、CharArrayWriter オブジェクト ObjectOutputStream/InputStream
どこから ファイル FileOutputStream/InputStream/Reader/Writer String StringReader/Writer (Stringから読み込むのでStreamのものはない) 他のストリーム InputStreamReader ・・・・
例えば 次のクラスの役割を考えてみてください FileReader ObjectInputStream ファイルから文字列を入力するクラス ByteArrayOutputStream ファイルから文字列を入力するクラス オブジェクトを入力するクラス バイト列をbyte型の配列に出力するクラス
②機能を付与するもの BufferedReader 文字列をバッファリングすることによって、 文字列を一行ずつ読み込んだりする機能を 提供するクラス PrintWriter 文字列や整数などをストリームに対して 直接書き込む機能を提供するクラス
使用例 BufferedReader br= new BufferdeReader(new InputStream(System.in)); String 入力=br.readLine(); コンソールから受け取った入力ストリームを引数にとっている コンソールからの入力を一行単位で読み込む 機能を提供している
使用例② PrintWriter pw = new PrintWriter(new FileWriter("test.txt")); pw.println("test"); ファイルへの出力ストリームを引数にとっている ファイルへの出力を文字列単位で行う 機能を提供している
まとめ Java.ioパッケージに含まれるクラスの役割は ぱっと見わかりにくい印象を受ける 何をどこへどのように入出力したいのかを考え 適切な入出力クラスを使うようにする
今日の課題 スケルトンとして配られたプログラムに 入出力の部分を書き足して自販機を 永続化してください お疲れ様でした・・・・