Javaでプロパティファイルを使いこなすたった7つの方法

Javaプロパティファイル使用方法の解説イメージJava
この記事は約29分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、Javaでプロパティファイルを使いこなすことができるようになります。

プロパティファイルって何?という方から、もう少し高度な使い方を知りたいという方まで、幅広く解説します。

プロパティファイルは設定やデータを独立させて管理するための仕組みです。

これにより、プログラムが柔軟でメンテナンスがしやすくなります。

しかし、使い方を間違えると、かえって複雑なシステムになってしまうこともあります。

そこで、この記事では基本的な使い方から応用例、そして注意点までを網羅しています。

●Javaとプロパティファイルについて

○Javaとは

Javaは、多くのアプリケーションで使用されるプログラミング言語です。

特に企業システムなど、大規模なアプリケーション開発においてよく用いられます。

Javaで書かれたプログラムは、Java Virtual Machine(JVM)上で動作するため、OSに依存しないのが特長です。

○プロパティファイルとは

プロパティファイルは、.propertiesという拡張子を持つテキストファイルで、設定データや環境変数、言語リソースなどを格納します。

プロパティファイルはキーと値のペアでデータを管理し、Javaプログラムから簡単に読み取ることができます。

たとえば、データベースの接続情報やAPIキー、環境依存の設定など、プログラムから分離して管理したい情報を保存するのに便利です。

これにより、ソースコードの変更なしに設定を変更したり、異なる環境での動作を容易にすることができます。

プロパティファイルを使うことで、ソースコード内から設定情報を分離できるので、プログラムが見やすくなり、保守もしやすくなります。

また、設定情報だけを変更する場合に、プログラムをコンパイルし直す必要がなくなるので、作業効率が向上します。

●プロパティファイルの基本構造

さて、本題に入る前にプロパティファイルの基本構造について知っておくと、後の作業がスムーズに進みます。

○キーと値のペア

プロパティファイルでは、データは「キー」と「値」のペアとして保存されます。

通常、このフォーマットは以下のようになります。

# データベースの設定
db_host=localhost
db_user=root
db_password=secret

Javaでこれを読み込む基本的なコードは次の通りです。

import java.util.Properties;
import java.io.FileReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティファイルを読み込む
        try (FileReader reader = new FileReader("config.properties")) {
            properties.load(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 値を取得する
        String dbHost = properties.getProperty("db_host");
        String dbUser = properties.getProperty("db_user");
        String dbPassword = properties.getProperty("db_password");

        // 結果を出力
        System.out.println("DB Host: " + dbHost);
        System.out.println("DB User: " + dbUser);
        System.out.println("DB Password: " + dbPassword);
    }
}

このコードではPropertiesクラスを用いて、config.propertiesファイルを読み込んでいます。

読み込んだ後、getPropertyメソッドで各キーに対応する値を取得しています。

このコードを実行すると、コンソールには次のように出力されます。

DB Host: localhost
DB User: root
DB Password: secret

○コメントの書き方

プロパティファイル内でコメントを書く場合は、#または!を行の先頭に付けます。

例えば、次のように記述できます。

# これはコメントです
! これもコメントです

# データベースの設定
db_host=localhost

コメントはプログラムには影響を与えませんが、設定ファイルを読む人にとっては非常に有用です。

●プロパティファイルの読み込み

プロパティファイルをJavaで効率よく扱うためには、その読み込み方を理解することが基礎となります。

Javaでは主にPropertiesクラスやFileInputStreamを用いた方法があります。

それぞれに特徴と適用シーンがあるため、注意深く選ぶ必要があります。

○サンプルコード1:Properties クラスを使って読み込む

まず最初に、Propertiesクラスを使ったプロパティファイルの読み込み方について説明します。

import java.util.Properties;
import java.io.FileReader;
import java.io.IOException;

public class ReadProperties {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティファイルの読み込み
        try (FileReader reader = new FileReader("settings.properties")) {
            properties.load(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // プロパティの使用
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println("Username: " + username);
        System.out.println("Password: " + password);
    }
}

このJavaコードは、settings.propertiesという名前のプロパティファイルからusernamepasswordというキーの値を読み取っています。

具体的には、Propertiesクラスのloadメソッドでプロパティファイルを読み込み、getPropertyメソッドで値を取得しています。

このコードを実行した場合、settings.propertiesに次のような内容が書かれていると仮定します。

username=admin
password=1234

その結果、コンソール出力は「Username: admin」と「Password: 1234」と表示されるでしょう。

○サンプルコード2:FileInputStreamを使って読み込む

次に、FileInputStreamを使った読み込み方法です。

この方法は特に大きなプロパティファイルを効率よく読み込む場合に有用です。

import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;

public class ReadPropertiesWithStream {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティファイルの読み込み
        try (FileInputStream stream = new FileInputStream("settings.properties")) {
            properties.load(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // プロパティの使用
        String host = properties.getProperty("host");
        String port = properties.getProperty("port");

        System.out.println("Host: " + host);
        System.out.println("Port: " + port);
    }
}

このコードではFileInputStreamsettings.propertiesという名前のプロパティファイルを開き、そのストリームをPropertiesクラスのloadメソッドに渡しています。

読み込みが完了したら、getPropertyhostportの値を取得しています。

仮にsettings.propertiesに次のような内容が含まれていた場合、

host=localhost
port=8080

このコードを実行すると、「Host: localhost」および「Port: 8080」という結果がコンソールに出力されることになります。

●プロパティファイルの書き込み

Javaでプロパティファイルを扱うスキルを向上させるためには、ただ読み込むだけでなく書き込むことも非常に重要です。

ここでは、Javaでプロパティファイルにデータを書き込む基本的な2つの方法について説明します。

それはPropertiesクラスとFileOutputStreamを使う方法です。

○サンプルコード3:Properties クラスを使って書き込む

JavaのPropertiesクラスは、プロパティファイルにデータを書き込む機能も提供しています。

import java.util.Properties;
import java.io.FileWriter;
import java.io.IOException;

public class WriteProperties {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティに値を設定
        properties.setProperty("username", "admin");
        properties.setProperty("password", "1234");

        // プロパティファイルへの書き込み
        try (FileWriter writer = new FileWriter("settings.properties")) {
            properties.store(writer, "User Settings");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

このコードでは、まずPropertiesクラスのインスタンスを作成し、setPropertyメソッドでキーと値を設定しています。

その後、storeメソッドを使用してプロパティ情報をsettings.propertiesに保存しています。

このコードを実行すると、settings.propertiesusernamepasswordが書き込まれます。

ファイルの内容は次のようになります。

#User Settings
username=admin
password=1234

○サンプルコード4: FileOutputStreamを使って書き込む

もう一つの方法は、FileOutputStreamを使う手法です。

import java.util.Properties;
import java.io.FileOutputStream;
import java.io.IOException;

public class WritePropertiesWithStream {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティに値を設定
        properties.setProperty("host", "localhost");
        properties.setProperty("port", "8080");

        // プロパティファイルへの書き込み
        try (FileOutputStream stream = new FileOutputStream("server_settings.properties")) {
            properties.store(stream, "Server Settings");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

この例では、FileOutputStreamオブジェクトを作成し、それをPropertiesクラスのstoreメソッドに渡しています。

この方法は大量のデータやバイナリデータを扱う場合にも有用です。

実行後、server_settings.propertiesファイルに次のような内容が書き込まれるでしょう。

#Server Settings
host=localhost
port=8080

●プロパティファイルでのエンコーディング

プロパティファイルをJavaで扱う場合、エンコーディングも重要な要素の一つです。

ここでは、UTF-8とISO-8859-1のエンコーディング方式による読み書きについて説明します。

○UTF-8での読み書き

UTF-8は現代の多くのシステムで標準とされているエンコーディング形式です。

UTF-8でのプロパティファイルの読み書きは次のようなサンプルコードで実現できます。

import java.io.*;
import java.util.Properties;

public class PropertiesUTF8Example {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        // プロパティに値を設定(UTF-8で日本語も設定可能)
        properties.setProperty("言語", "日本語");
        properties.setProperty("message", "こんにちは");

        // UTF-8で書き込み
        try (OutputStreamWriter writer = new OutputStreamWriter(
                 new FileOutputStream("utf8_properties.properties"), "UTF-8")) {
            properties.store(writer, "UTF-8 Settings");
        }

        // UTF-8で読み込み
        Properties loadedProperties = new Properties();
        try (InputStreamReader reader = new InputStreamReader(
                 new FileInputStream("utf8_properties.properties"), "UTF-8")) {
            loadedProperties.load(reader);
        }

        System.out.println(loadedProperties.getProperty("言語"));  // 出力: 日本語
        System.out.println(loadedProperties.getProperty("message"));  // 出力: こんにちは
    }
}

このサンプルコードでは、OutputStreamWriterInputStreamReaderを用いてUTF-8でのエンコーディングを明示しています。

書き込みと読み込みでそれぞれUTF-8を指定しています。

このコードを実行すると、日本語も含めて正確にプロパティが読み書きされ、コンソールには「日本語」と「こんにちは」と出力されます。

○ISO-8859-1での読み書き

一方、ISO-8859-1(別名: Latin-1)は、欧州言語のテキスト表現に特化したエンコーディング方式です。

このエンコーディング形式は、JavaのPropertiesクラスのデフォルトエンコーディングです。

下記のサンプルコードでは、ISO-8859-1での読み書きが行われています。

import java.util.Properties;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class PropertiesISOExample {
    public static void main(String[] args) {
        Properties properties = new Properties();

        // プロパティに値を設定(ISO-8859-1の範囲内の文字を使用)
        properties.setProperty("language", "English");
        properties.setProperty("message", "Hello");

        // 書き込み
        try (FileOutputStream stream = new FileOutputStream("iso_properties.properties")) {
            properties.store(stream, "ISO-8859-1 Settings");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 読み込み
        Properties loadedProperties = new Properties();
        try (FileInputStream stream = new FileInputStream("iso_properties.properties")) {
            loadedProperties.load(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(loadedProperties.getProperty("language"));  // 出力: English
        System.out.println(loadedProperties.getProperty("message"));  // 出力: Hello
    }
}

このコードでは、Propertiesクラスのデフォルトのstoreおよびloadメソッドを使っています。

ISO-8859-1に対応しているため、特にエンコーディングの指定はありません。

このコードを実行した際には、「English」と「Hello」がコンソールに出力されるでしょう。

●プロパティファイルの応用例

Javaのプロパティファイルは、単なる設定値の管理から多言語対応まで、多様な用途に使えます。

このセクションでは、プロパティファイルの応用例として次の3つの項目に焦点を当てます。

○サンプルコード5:多言語対応

多言語対応はプロパティファイルがよく用いられる用途の一つです。

特に、異なる言語のテキストリソースを管理する際に有用です。

下記のサンプルコードでは、日本語と英語のメッセージをプロパティファイルで管理しています。

import java.util.Locale;
import java.util.ResourceBundle;

public class MultilanguageExample {
    public static void main(String[] args) {
        // 英語のロケール設定
        ResourceBundle enBundle = ResourceBundle.getBundle("messages", Locale.ENGLISH);
        System.out.println(enBundle.getString("greeting"));

        // 日本語のロケール設定
        ResourceBundle jaBundle = ResourceBundle.getBundle("messages", Locale.JAPANESE);
        System.out.println(jaBundle.getString("greeting"));
    }
}

このコードでは、ResourceBundleクラスを用いていて、このクラスが言語ごとに適切なプロパティファイルを読み込む役割を果たしています。

言語が切り替わる場合、ResourceBundleがそれに応じて適切なプロパティファイルを使用します。

このコードを実行すると、英語で”Hello”と日本語で”こんにちは”と表示されます。

○サンプルコード6:設定値の一括管理

複数の設定値を一括で管理することも、プロパティファイルが得意とするタスクの一つです。

下記のサンプルコードでは、データベースの設定値をプロパティファイルで一括管理しています。

import java.util.Properties;
import java.io.InputStream;

public class DatabaseConfigExample {
    public static void main(String[] args) {
        Properties properties = new Properties();
        try (InputStream stream = DatabaseConfigExample.class.getResourceAsStream("/database.properties")) {
            properties.load(stream);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String url = properties.getProperty("db.url");
        String username = properties.getProperty("db.username");
        String password = properties.getProperty("db.password");

        System.out.println("URL: " + url);
        System.out.println("Username: " + username);
        System.out.println("Password: " + password);
    }
}

このコードでは、データベースのURL、ユーザーネーム、パスワードをプロパティファイルで管理し、それをPropertiesクラスで読み込んでいます。

コードを実行すると、設定ファイルに記述されたデータベースの設定情報がコンソールに出力されます。

○サンプルコード7:ネストされたプロパティ

最後に、プロパティのネスト(入れ子)によって複雑なデータ構造を表現する方法を説明します。

下記のサンプルコードでは、JSONライクな構造をプロパティファイルで模倣しています。

import java.util.Properties;

public class NestedPropertiesExample {
    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.setProperty("user.name", "Alice");
        properties.setProperty("user.email", "alice@example.com");
        properties.setProperty("user.phone.mobile", "090-1234-5678");
        properties.setProperty("user.phone.home", "03-1234-5678");

        String mobilePhone = properties.getProperty("user.phone.mobile");
        System.out.println("Mobile Phone: " + mobilePhone);
    }
}

こちらのコードでは、ユーザーの情報(名前、メール、電話番号)がプロパティとして設定されています。

特に、user.phone.mobileというようにドットで区切ってネストされたプロパティを表現しています。

このコードを実行すると、”Mobile Phone: 090-1234-5678″が出力されるでしょう。

●注意点と対処法

プロパティファイルを使用する際には、いくつか注意すべきポイントがあります。

ここでは、特に初心者から上級者まで共通して意識するべき二つの項目について詳しく説明します。

○特殊文字の扱い

プロパティファイルでは一般的にASCII文字しか正確に扱えません。

それ以上の特殊文字を使用する場合、Unicodeエスケープという方法で表現する必要があります。

下記のサンプルコードは、プロパティファイル内で特殊文字(例:日本語や記号)をどのように扱うかを表しています。

import java.io.FileOutputStream;
import java.util.Properties;

public class SpecialCharacterHandling {
    public static void main(String[] args) {
        Properties prop = new Properties();

        // Unicodeエスケープを用いて特殊文字を設定
        prop.setProperty("message", "\\u3053\\u3093\\u306B\\u3061\\u306F");  // こんにちは in Unicode

        try (FileOutputStream output = new FileOutputStream("config.properties")) {
            prop.store(output, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

このコードは、日本語の「こんにちは」をUnicodeエスケープ形式でプロパティファイルに保存しています。このようにすると、特殊文字も正確に扱えます。

このコードを実行した後、生成されたconfig.propertiesファイルを開くと、message=\u3053\u3093\u306B\u3061\u306Fという行が含まれていることが確認できるでしょう。

○大量のデータを扱う際の注意点

プロパティファイルは、基本的には小規模な設定データの保存に適しています。

しかし、大量のデータを保存しようとすると、読み込みや書き込みのパフォーマンスが低下する可能性があります。

下記のサンプルコードは、大量のキーと値のペアをプロパティファイルに書き込む一例です。

import java.io.FileOutputStream;
import java.util.Properties;

public class LargeDataHandling {
    public static void main(String[] args) {
        Properties prop = new Properties();

        // 大量のデータを追加
        for (int i = 0; i < 10000; i++) {
            prop.setProperty("key" + i, "value" + i);
        }

        try (FileOutputStream output = new FileOutputStream("large_config.properties")) {
            prop.store(output, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

このコードでは、key0からkey9999まで、それぞれに対応するvalue0からvalue9999までの値を設定しています。

しかし、このような大量のデータを扱う場合、読み込みや書き込みの速度が遅くなる可能性があります。

このサンプルコードを実行すると、large_config.propertiesという名前のプロパティファイルが生成され、その中に大量のキーと値が保存されます。

●カスタマイズ方法

Javaでプロパティファイルを使いこなすための高度なカスタマイズ方法について解説します。

特に、プロパティの継承とカスタムローダーの作成に焦点を当てます。

○プロパティの継承

JavaのPropertiesクラスは継承をサポートしています。

これを利用して、一つのプロパティファイルから別のプロパティファイルに設定を継承させることが可能です。

import java.util.Properties;

public class PropertyInheritance {
    public static void main(String[] args) {
        // 親プロパティ
        Properties parentProperties = new Properties();
        parentProperties.setProperty("key1", "parentValue1");
        parentProperties.setProperty("key2", "parentValue2");

        // 子プロパティ
        Properties childProperties = new Properties(parentProperties);
        childProperties.setProperty("key2", "childValue2");
        childProperties.setProperty("key3", "childValue3");

        // 子プロパティを用いて値を取得
        String value1 = childProperties.getProperty("key1");
        String value2 = childProperties.getProperty("key2");
        String value3 = childProperties.getProperty("key3");

        // 結果を出力
        System.out.println("key1: " + value1); // 継承された値
        System.out.println("key2: " + value2); // 上書きされた値
        System.out.println("key3: " + value3); // 子プロパティに追加された値
    }
}

このコードでは、親プロパティと子プロパティを作成しています。

親プロパティにはkey1key2が設定されており、子プロパティでは親プロパティの設定を継承しつつ、key2の値を上書きし、key3を新たに追加しています。

このコードを実行すると、コンソールに次のような出力がされます。

key1: parentValue1
key2: childValue2
key3: childValue3

key1は親プロパティから継承され、key2は上書きされ、key3は新たに追加された値が反映されていることが確認できます。

○カスタムローダーの作成

プロパティファイルの読み込み方法をカスタマイズしたい場合には、独自のローダーを作成することができます。

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class CustomLoader {
    public static Properties loadCustomProperties(String filePath) {
        Properties prop = new Properties();
        try (FileInputStream input = new FileInputStream(filePath)) {
            // カスタマイズした読み込み処理(例:コメント行を無視する)
            prop.load(input);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return prop;
    }

    public static void main(String[] args) {
        Properties properties = loadCustomProperties("config.properties");
        // 読み込んだプロパティを利用する処理
    }
}

このサンプルコードでは、loadCustomPropertiesというメソッドを作成しています。

このメソッドでは、特定の条件に基づいてプロパティファイルを読み込むカスタマイズが可能です。

例として、コメント行を無視するような処理が入れられる場合もあります。

このメソッドを利用してプロパティファイルを読み込むと、カスタマイズした読み込み処理が適用されます。

まとめ

Javaでプロパティファイルを使いこなすための多角的な視点からの解説を行いました。

Java自体が多機能であり、プロパティファイルもその柔軟性を十分に活かすことができる素材です。

我々が考慮すべき点として、読み込みや書き込みだけでなく、エンコーディングやカスタマイズも重要です。

このように多くの要素が影響を与えるため、一つ一つの要素を理解し、状況に応じて適切な選択をすることが、効率的なプロパティファイルの管理に繋がります。

プロパティファイルの活用は、設定管理はもちろん、多言語対応や大量のデータを扱う場面でもその価値を発揮します。

この記事を参考に、Javaプログラミングにおけるプロパティファイルの効果的な使い方を探究してみてください。