HOWTO · Java
Java のプロパティファイル
この記事では、Java のプロパティファイルについて説明します。
このページの内容
Java の Properties クラスは、アプリケーションの設定をキーと値のペアとして保持します。通常は .properties 拡張子のファイルに保存します。setProperty() で文字列のキーと値を追加し、store() で保存、load() で読み込み、getProperty() で設定を1つ取得できます。読み込んだエントリを確認するには list() を使います。
.properties ファイルの操作は、Java チュートリアル のファイル入出力とプロパティのグループで扱われ、Java の設定ガイドが集められています。
Java のプロパティファイルで値を作成して設定する
プロパティファイルでは、1行につき1つのエントリを記述します。たとえば、version=1.1 と projectName=PropertiesFileExample は別々のエントリです。行頭が # または ! の行はコメントとして扱われます。キーと値の区切りには =、:、または空白を使えます。キーの前にある空白は無視され、値には空白を含められます。setProperty() で各ペアを追加し、続けて store() を呼び出すと、コレクションと任意のコメントをファイルに書き込めます。
次の例を実行します。
このセクションのコードと表示されるラベルや出力は英語のままです。
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties properties = new Properties();
properties.setProperty("version", "1.1");
properties.setProperty("projectName", "PropertiesFileExample");
properties.setProperty("date", "2021/12/27");
try (OutputStream output = Files.newOutputStream(file)) {
properties.store(output, "Application settings");
}
}
}
Files.newOutputStream() は、ファイルがなければ作成し、すでにある場合は内容を切り詰めます。親ディレクトリはあらかじめ存在している必要があります。この例では、先に一時ディレクトリを作成します。try-with-resources ブロックを使うと、書き込みに失敗した場合もストリームが閉じられます。固定のパスを使う場合は、ファイルを開く前に親ディレクトリを作成してください。store() はエントリに加えてコメントと生成時刻も書き込むため、これらのコメント行は実行のたびに変わります。OutputStream を使う場合、非ラテン文字はプロパティファイルの形式に従ってエスケープされます。文字コードを明示的に選びたい場合は Writer を使えます。
java.io を使うコードでは、new FileOutputStream(path) も同じくファイルを作成し、既存ファイルがあれば内容を切り詰めます。また、親ディレクトリが必要です。上のストリームと同様、try-with-resources で閉じてください。
Java のプロパティファイルから値を取得する
設定を取得するには、保存したファイルを入力用に開き、Properties オブジェクトで load() を呼び出してから、取得したいキーを getProperty() に渡します。この例は1回の実行内でファイルへの書き込みと読み込みを行うため、別のプログラムが残したファイルには依存しません。入力ストリームにも try-with-resources を使い、読み込み後にファイルを解放します。
このセクションのコードと表示されるラベルや出力は英語のままです。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties saved = new Properties();
saved.setProperty("date", "2021/12/27");
try (OutputStream output = Files.newOutputStream(file)) {
saved.store(output, "Application settings");
}
Properties loaded = new Properties();
try (InputStream input = Files.newInputStream(file)) {
loaded.load(input);
}
String date = loaded.getProperty("date");
System.out.println(date == null ? "No date setting" : date);
}
}
キーが存在しない場合、getProperty() はエラーを投げずに null を返します。設定が任意なら null を確認するか、getProperty("theme", "light") のように既定値を指定してください。ファイルがない、パスを読み取れないなどの問題は別で、ファイルを開くときや読み込むときに IOException が発生することがあります。アプリケーションの境界で状況が分かるメッセージを表示するか、呼び出し元に復旧方法を決めてもらいます。この例では値の取得処理を分かりやすくするため、main に IOException を宣言しています。実際のアプリケーションでは、通常、状況に応じた情報を示せる場所で例外を捕捉します。
Java のプロパティファイルからすべてのキーと値を取得する
コンソールで手早く確認するには、ファイルを読み込んで System.out を渡し、list() を呼び出します。次の完全な例では、まず入力ファイルを作成し、その後、読み込んだエントリを表示します。出力に複数のキーと値のペアが示されるよう、2つ目の設定も含めています。
このセクションのコードと表示されるラベルや出力は英語のままです。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties saved = new Properties();
saved.setProperty("version", "1.1");
saved.setProperty("projectName", "PropertiesFileExample");
try (OutputStream output = Files.newOutputStream(file)) {
saved.store(output, "Application settings");
}
Properties loaded = new Properties();
try (InputStream input = Files.newInputStream(file)) {
loaded.load(input);
}
loaded.list(System.out);
}
}
list() は読みやすい診断用の一覧を表示するためのもので、汎用的な反復処理 API ではありません。表示形式やエントリの順序は、解析や比較に使える安定した形式ではありません。アプリケーションでエントリを処理する場合は、Properties のエントリまたはキーを反復処理し、各値を文字列として扱ってください。順序やコメントが重要なら、元のファイルを正本として保持します。プロパティの保存は設定データのためのものであり、list() はメモリに読み込まれている値を表示するだけです。