Javaでファイルから設定値を読み込む（簡易的な方法）

今回ご紹介するのはファイルから設定値を読み込む方法です。
XMLを使ったりいろいろ方法はあると思いますが、
今回は比較的簡易な方法をご紹介します。

#今回読み取りたいファイルの形式
例えば以下のようなファイルを読み取りたいとします。

```:mysettings.env
#読み取りたいファイルです
UserID = 1234
Gender = Male
```

\#から行末まではコメントとみなされます。
=の左が設定名、右が設定値となっており、一行一つ設定が書かれます。
=の前後に空白が入っている場合は、それらを取り除いて読み取ります。
つまり、設定名や設定値が「UserID 」、「 1234」などにはならないということです。

#使用するメソッド
今回使用するのはjava.util.Properties.loadです。
このメソッドを用いるとwindowsのiniファイルのような
key=value型の書き方をするファイルから設定値を読み取れます。
また、今回はご紹介しませんが、Propertiesクラスにはxmlからファイルを読み取るメソッドもあります。

[公式のリファレンス](https://docs.oracle.com/javase/jp/6/api/java/util/Properties.html)ではPropertiesクラスは以下のように説明されています。
>Properties クラスは、不変のプロパティーセットを表します。Properties を、ストリームへ保管したり、ストリームからロードしたりできます。プロパティーリストの各キー、およびそれに対応する値は文字列です。

説明の通り、設定はキー、値ともにまずは文字列として取得されます。


#コード例
コードとしては、例えば以下のようになります。

```java:Main.java
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class Main {
	private static final String PROPERTY_FILE = "mysettings.env"; ///< 読み取りたい設定ファイル

	public static void main(String[] args) {

		try {
			// 設定ファイルを読み取る処理
			Properties property = new Properties();
			property.load(new FileInputStream(PROPERTY_FILE));
			
			// 読み取ったものから実際に設定値を取り出す処理
			String uid = property.getProperty("UserID");
			String gender = property.getProperty("Gender", "unknown");

			System.out.println(String.format("UserID:%s", uid));
			System.out.println(String.format("Gender:%s", gender));

		} catch (IOException e) {
			// ファイルの読み込みエラー
			e.printStackTrace();
			return;
		}

	}

}
```

property.loadで好きなファイルを指定し（当然拡張子含めて何でもよい）、
property.getPropertyでキーを指定して設定値を取得します。
property.getProperty("Gender", "unknown");のように書くと指定する設定がなかった場合は二番目の引数を返します。

#実行結果
これを最初に出したmysettings.envを用いて実際に実行すると以下のような出力が返ってきます。

```
UserID:1234
Gender:Male
```

UserIDがnullになった場合は、loadで指定するstreamをFile.BufferedReaderなどに変えて、文字コードに明示的にUTF-8を指定してください。
あるいはファイル側の文字コードをshift_jisに変えてください。


#設定ファイルの細かい仕様（SE8の公式リファレンスより）
実行結果は上記のコードを使用しています。

###コメントの開始記号は「!」または「\#」

```:入力ファイル
UserID = 1234
!Gender = Male
#Gender = Female
```

```:出力結果
UserID:1234
Gender:unknown
```


###空白として無視されるのは行末記号 (\n、\r、または \r\n) 、スペース (' ', '\u0020')、タブ ('\t', '\u0009')、およびフォームフィード ('\f', '\u000C')

```:入力ファイル
UserID =	1234
Gender = Male
```

```:出力結果
UserID:1234
Gender:Male
```


###キーと値の区切り文字は「=」、「:」、または改行を除く空白

```:入力ファイル
UserID	1234
Gender:Male
```

```:出力結果
UserID:1234
Gender:Male
```

###複数行にわたって値を設定したいときは「\（バックスラッシュ）」を使う
複数行になっている部分は、空白が取り除かれて連結されます。

```:入力ファイル
UserID = 1234\
		5678
Gender:Male
```

```:出力結果
UserID:12345678
Gender:Male
```


###「\（バックスラッシュ）」や「=」などを設定値に含めたいときは「\（バックスラッシュ）」でエスケープする

```:入力ファイル
UserID=12\\3\=4
Gender=Male
```

```:出力結果
UserID:12\3=4
Gender:Male
```

###設定値がない時は、空白文字列が指定されたと判断する（デフォルトの値は使われない）

```:入力ファイル
UserID=1234
Gender
```

```:出力結果
UserID:1234
Gender:
```

地味に引っ掛かりそうなポイントです。
<br>
<br>
以下は検証してわかったことです。
###設定値が複数あるときは、最後の値が使われる模様

```:入力ファイル
UserID=1234
UserID=5678
Gender=Male
```

```:出力結果
UserID:5678
Gender:Male
```

###「""」があるときは、取り除かれずに取り込まれる模様

```:入力ファイル
UserID = "1234"
Gender = Male
```

```:出力結果
UserID:"1234"
Gender:Male
```

###設定値の中に空白が含まれる場合は取り除かれずに取り込まれる模様

```:入力ファイル
UserID = 12 34
Gender = Male
```

```:出力結果
UserID:12 34
Gender:Male
```

以上です。