smalltech
@smalltech

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Java Propertiesクラスを用いて書き込みを行う際の文字について

Q&A

Closed

環境

macOS 10.15.4
Adopt OpenJDK 11.0.8

質問

下記のようにjava.util.Propertiesクラスを使用してプロパティファイルを作成しようと思うのですが、出力結果のコメント部分がUnicodeエスケープシーケンスになってしまうようです。データの部分は漢字がそのまま出ているのになぜコメント部分だけこうなるのでしょう?

コード

Main.java
import java.io.*;
import java.util.*;

public class Main {
  public static void main(String[] args) throws Exception {
    Writer fw = new FileWriter("test.properties");
    Properties p = new Properties();
    p.setProperty("Name", "太郎");
    p.store(fw, "あ");
    fw.close();
  }
}

実行結果

test.properties
#\u3042
#Fri Aug 21 18:45:19 JST 2020
Name=太郎

1行目の\u3042という部分が「あ」になって欲しいのですが。。。

ちなみにFileWriterで文字コードを指定しなければいけないのかと思い、下記のように少し変更したコードを試しましたが同じ結果でした。

Main.java
import java.io.*;
import java.util.*;
import java.nio.charset.Charset;

public class Main {
  public static void main(String[] args) throws Exception {
    Writer fw = new FileWriter("test.properties", Charset.forName("UTF-8"));
    Properties p = new Properties();
    p.setProperty("Name", "太郎");
    p.store(fw, "あ");
    fw.close();
  }
}

0

2Answer

気になって調べてみましたが、結論から言うとできませんね。

提示の方法が何か間違ってるわけではなく、store の実装が
「コメントは(出力先の文字コードに関らず)、U+00ff より大きいものをエスケープする」
という実装になってしまっているためです。

java.util.Properties#writeComments

どうしてもと言う場合は、.properties を出力する部分を自作する他ない気がします。

0Like

Comments

  1. @smalltech

    Questioner

    @nagtkk さん

    回答いただきありがとうございます。リンクも教えていただいて助かりました。

    >提示の方法が何か間違ってるわけではなく、store の実装が
    >「コメントは(出力先の文字コードに関らず)、U+00ff より大きいものをエスケープする」
    >という実装になってしまっているためです。

    見てきましたが確かにそのようでした。なぜなんでしょうね。

    「writeCommentsにもescUnicodeを渡すことにして、値がfalseの場合エスケープしないことにする」とすれば良いような気がしますが難しいんですかねー。それとも他に理由があるのか。
    (writeCommentsの処理見た感じ、素人考えだと、ざっくり言って改行コードが入った時に「#」打つ以外は普通にwriteすれば良いように思えます。。writeするとまずい文字とかあるのでしょうか)

    >どうしてもと言う場合は、.properties を出力する部分を自作する他ない気がします。

    ザーッと勉強していてぶつかった感じなので、今はそこまでって感じですが、言われてみれば出力を実装するだけなら難しくないのかもしれませんね(コメントの文字列は多少制限するとして)。

    何はともあれ元々の疑問は解決しました。ありがとうございました。
  2. 確かに色々と腑に落ちませんね。

    まあ、API 見ていくと、Reader/Writer 受け取れるようになったのが Java6 からで、
    それまでは ISO 8859-1 (いわゆる Latin-1) での読み書きしか考えてないっぽいので、
    そのころの名残(そして放置)って感じなんでしょうね……。

これでもいいのでは?

try (Writer fw = new FileWriter("data/test.properties")) {
    Properties p = new Properties();
    p.setProperty("Name", "太郎");
    fw.write("# あ" + System.lineSeparator());
    p.store(fw, null);
}
0Like

Comments

  1. @smalltech

    Questioner

    @saka1029 さん
    ご回答ありがとうございます。

    そうですね!テキストファイルとして書ければいいというものだと思いますので、
    現状、お示しいただいた方法が一番ラクな気がします。
    (Propertiesクラスの機能でコメントを書くのではなく、そこはnullにしておいて、FileWriterで直にコメント部分を出力するということですよね)

    ちょっと今は色々じっくり見れないので、追々詳しく見たいと思います。
    ありがとうございました!

Your answer might help someone💌