XML形式のプロパティファイル読み書きメモ

XML 形式のプロパティファイルを読み書きする方法メモ。

#環境
##OS
Windows7 64bit

##Java
1.7.0_25

#書き出し
##実装
```java:プロパティファイルの書き出し
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Properties;

public class Main {
    
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        prop.setProperty("hoge", "ほげ");
        prop.setProperty("fuga", "ふが");
        prop.setProperty("piyo", "ぴよ");
        
        try (OutputStream os = new FileOutputStream("prop.xml")) {
            prop.storeToXML(os, "コメント");
        }
    }
}
```

##書き出し結果
```xml:prop.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>コメント</comment>
<entry key="piyo">ぴよ</entry>
<entry key="fuga">ふが</entry>
<entry key="hoge">ほげ</entry>
</properties>
```

#読み込み
##実装
```java:プロパティファイルの読み込み
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map.Entry;
import java.util.Properties;

public class Main {
    
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        InputStream is = new FileInputStream("prop.xml");
        
        prop.loadFromXML(is); // is はこのメソッドが終了すると close される
        
        for (Entry<Object, Object> entry : prop.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
}
```

##読み込み結果
```text:標準出力
piyo = ぴよ
fuga = ふが
hoge = ほげ
```



#`storeToXML()` と `loadFromXML()` で引数のストリームの扱いが若干違う
`storeToXML()` はメソッドが終了しても引数のストリームはクローズされないが、 `loadFromXML()` はメソッドが終了すると引数のストリームはクローズされる。

[storeToXML | Properties (Java Platform SE 7)](http://docs.oracle.com/javase/jp/7/api/java/util/Properties.html#storeToXML%28java.io.OutputStream,%20java.lang.String,%20java.lang.String%29)

> 指定されたストリームは、このメソッドが復帰したあとも __開いたままです__ 。

[loadFromXML | Properties (Java Platform SE 7)](http://docs.oracle.com/javase/jp/7/api/java/util/Properties.html#loadFromXML%28java.io.InputStream%29)

> このメソッドが戻ると、指定されたストリームが __閉じられます__ 。



#文字コードの指定について
読み書きは、実行環境に関係なくデフォルト `UTF-8` で行われる。

[Properties (Java Platform SE 7)](http://docs.oracle.com/javase/jp/7/api/java/util/Properties.html)

> loadFromXML(InputStream) および storeToXML(OutputStream, String, String) メソッドは、プロパティーを単純な XML 形式としてロードおよび格納できます。 __デフォルトでは UTF-8 文字エンコーディングが使用されます__ が、必要に応じてエンコーディングを指定できます。

なので、 特に文字コードを明示的に指定する必要はないっぽい。

エンコーディングを指定したい場合は、 `loadFromXML()` の第三引数で指定する。
読み込みの時は、 XML の先頭にエンコードが記述されているので、コード上での指定は不要っぽい。

```java:Shift_JISを指定
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map.Entry;
import java.util.Properties;

public class Main {

    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        prop.setProperty("hoge", "ほげ");
        prop.setProperty("fuga", "ふが");
        prop.setProperty("piyo", "ぴよ");

        try (OutputStream os = new FileOutputStream("prop.xml")) {
            prop.storeToXML(os, "コメント", "Shift_JIS");
        }
        
        prop = new Properties();
        
        InputStream is = new FileInputStream("prop.xml");
        prop.loadFromXML(is);
        
        for (Entry<Object, Object> entry : prop.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
} 
```

```xml:prop.xml
<?xml version="1.0" encoding="Shift_JIS" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>コメント</comment>
<entry key="piyo">ぴよ</entry>
<entry key="fuga">ふが</entry>
<entry key="hoge">ほげ</entry>
</properties>
```

#参考
- [ArdorCode: JavaでXMLプロパティの読み書きを行う](http://ardorcode.blogspot.jp/2012/05/xml-link-xmlproperties-author-ardor.html)
- [Properties (Java Platform SE 7)](http://docs.oracle.com/javase/jp/7/api/java/util/Properties.html)