XMLDecoderを使用したデータの読み込み
それでは今度は前述の方法で、XML形式で保存されたファイルからデータを復元してみます。データからDataSetオブジェクトを復元するには、XMLDecoderクラスを使用します。
例として、次のようなコードを作成します。
import java.beans.XMLDecoder; import java.io.*; public class XMLDecoderTest { final static String FILE_NAME = "test.xml"; public static void main(String[] args) { DataSet dataSet = null; try { XMLDecoder dec = new XMLDecoder( new BufferedInputStream( new FileInputStream(FILE_NAME))); dataSet = (DataSet)dec.readObject(); dec.close(); } catch(FileNotFoundException e) { e.printStackTrace(); return; } System.out.println("score=" + dataSet.getScore()); System.out.println("name=" + dataSet.getName()); } }
上記のコードを実行すると次のように出力され、保存した情報が復元されたことを確認できます。
score=100 name=太郎
以上に述べた方法で、ファイルへのデータの書き出しと復元を実現できました。DataSetの内容を適宜変更することで、独自の情報を簡単にXML形式で読み書きできるようになります。
これ以降では、複数のオブジェクトを保存する方法と、配列を含むデータの例について紹介します。
複数のオブジェクトの保存
複数のオブジェクトを保存するには配列を使用します。XMLEncoderクラスのwriteObjectメソッドには配列をそのまま渡すことができるので、次のような簡単なコードで実現できます。
import java.beans.XMLEncoder; import java.io.*; public class XMLEncoderTest { final static String FILE_NAME = "test.xml"; public static void main(String[] args) { DataSet dataSetArray[] = { new DataSet(100, "太郎"), new DataSet( 90, "二郎"), new DataSet( 80, "三郎"), }; try { XMLEncoder encoder = new XMLEncoder( new BufferedOutputStream( new FileOutputStream(FILE_NAME))); encoder.writeObject(dataSetArray); encoder.close(); } catch(Exception e) { e.printStackTrace(); } } }
上記のコードを実行して生成されたXMLファイルの中身は次のようになっています。
<?xml version="1.0" encoding="UTF-8"?> <java version="1.5.0_02" class="java.beans.XMLDecoder"> <array class="DataSet" length="3"> <void index="0"> <object class="DataSet"> <void property="name"> <string>太郎</string> </void> <void property="score"> <int>100</int> </void> </object> </void> <void index="1"> <object class="DataSet"> <void property="name"> <string>二郎</string> </void> <void property="score"> <int>90</int> </void> </object> </void> <void index="2"> <object class="DataSet"> <void property="name"> <string>三郎</string> </void> <void property="score"> <int>80</int> </void> </object> </void> </array> </java>
配列に含まれる3つのオブジェクトの情報が書き出されていることを確認できます。これを読み込むには、次のようにXMLDecoderクラスのreadObjectメソッドの戻り値をDataSet[]型にキャストするだけで済みます。
import java.beans.XMLDecoder; import java.io.*; public class XMLDecoderTest { final static String FILE_NAME = "test.xml"; public static void main(String[] args) { DataSet dataSetArray[] = null; try { XMLDecoder dec = new XMLDecoder( new BufferedInputStream( new FileInputStream(FILE_NAME))); dataSetArray = (DataSet[])dec.readObject(); dec.close(); } catch(FileNotFoundException e) { e.printStackTrace(); return; } for(int i = 0; i < dataSetArray.length; i++) { System.out.println("--" + i + "--"); System.out.println("score=" + dataSetArray[i].getScore()); System.out.println("name=" + dataSetArray[i].getName()); } } }
上記のXMLDecoderTestを実行した結果の出力は次のようになります。複数のオブジェクトを復元できたことが確認できます。
--0-- score=100 name=太郎 --1-- score=90 name=二郎 --2-- score=80 name=三郎
配列を含むオブジェクトの保存
ファイルに書き出すオブジェクトの中に配列を持たせることも、もちろん可能です。例えば次の例のように、メンバ変数に配列を持たせ、その変数用のアクセッサを定義するだけで済みます。
public class DataSet { private int[] scoreArray; private String name; public DataSet() { scoreArray = null; name = "No Name"; } public DataSet(int[] scoreArray, String name) { this.scoreArray = scoreArray; this.name = name; } public void setScoreArray(int[] sa) { scoreArray = sa; } public int[] getScoreArray() { return scoreArray; } public void setName(String s) { name = s; } public String getName() { return name; } }
バイナリデータの保存
XMLファイルはテキスト形式ですので、ファイルの中にバイナリデータを含ませることはできません。バイナリデータを持つオブジェクトを書き出したい場合は、次の方法が考えられます。
- byte型の配列として保存する
- バイナリデータをBase64形式などに変換して文字列として保存する
前者の方法が簡単ですが、XMLファイルのサイズが大きくなってしまうという問題があります。後者の方法は、例えばJ2EEのjavax.mail.internet.MimeUtilityクラスのencode、decodeメソッドなどを使用して実現することができます。
まとめ
アプリケーションで作成したデータをファイルに書き出す仕組みと、そのファイルからデータを復元する仕組みを簡単に実装する方法として、XMLEncoderクラスとXMLDecoderクラスを活用する手法を紹介しました。
手順の流れを最後にまとめます。
- ファイルに保存するデータを保持するクラス(今回の例では
DataSetクラス)を定義します。ただし、このクラスは次のような決まりを守る必要があります。 - 引数のないデフォルトコントラスタが定義されている
- 変数に対するアクセッサ(set変数名、get変数名という名前のメソッド)が定義されている
XMLEncoderのwriteObjectメソッドを使用して、データを保持したインスタンスの情報をファイルに書き出します。XMLDecoderのreadObjectメソッドを使用して、データを保持したインスタンスを復元します。- インスタンスから必要に応じてデータを取り出します。
