PrintWriterでテキストを書き出しても改行がちゃんとされない理由

久々にPrintWriterでテキストファイルの書き出しをしていたら、
PCによって正しく改行されている場合とそうでない場合がありました。
予想外につまづいてしまったので、メモ。

結果から言うと、改行を表すエスケープシーケンス ”\n” は正しく書き出されていたのに対して、それを開くエディタが対応しているかしていないかの差でした。

実際に動かそうとしたのは次のようなコードです。

   try {
        // ファイルオープン
        PrintWriter pw = new PrintWriter("out.txt");
        // ファイルの書き込み
        pw.print(jTextArea.getText());
        // ファイルクローズ
        pw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

テキスト領域(jTextArea)に書き込んだ文章を getText() メソッドで取得し、それをそのままファイル(out.txt)書き出す処理になっています。「jTextArea.getText()」の部分は「”wa-\nwa-“」のような ”\n” を含む適当な文字列に置き換えても同じです。

まず、テキストエリアに入力された改行を getText() で取得した文字列のコードを見てみると、改行部分は ”\n” に変換されていました。しかし、これをメモ帳で開くと、改行コードは見えませんが改行はされていません。それに対して秀丸のような他のエディタで開くと、正しく改行が行われていました。

また、上記ソースコードを行ごとに分け、それぞれ println() メソッドを使えば、しっかりメモ帳でも改行がされます。改行の際には ”\n” ではなく println() メソッドを使うことが推奨されている理由がよくわかりました。

実際に println() で改行の際にどうなっているかを、次のコードで確認してみます。

String line = System.getProperty("line.separator");
for (int i = 0; i < line.length(); i++) {
    System.out.println("line[" + i + "] = " + (int) line.charAt(i));
}

結果は次のとおり。
==================
line[0] = 13
line[1] = 10
==================
文字コード13は行頭復帰を表す ”\r” 文字コード10は改行を表す ”\n” そういえばWindowsの環境下では「\r\n」が改行を意味するとかそんなことを聞いた覚えがあります。ファイル出力する際には改行部分に “\r\n” を入れないと、正しく表示されないんですね。println() メソッドではプラットフォームに合わせた改行文字を出力してくれるようです。そうであれば、jTextArea から getText() する際にも自動でプラットフォームに合わせて改行コードを変換して欲しいものです。このような書き方はあまり多くはないと思いますが。

最後に、今後使う状況があるのかどうかは謎ですが、テキスト領域から取得した文章の改行コードをプラットフォームに合わせて置き換え、テキストファイルに書き出すプログラムの例を書いておきます。

   try {
        // ファイルオープン
        PrintWriter pw = new PrintWriter("out.txt");
        // ファイルの書き込み
        String text = jTextArea.getText();
        text.replaceAll("\n", System.getProperty("line.separator"));
        pw.print(text);
        // ファイルクローズ
        pw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

はじめのうちは、Javaのバージョンが違うせいかと思ってせっせに色んなバージョンを試していましたが、時間の無駄でした。

タイトルとURLをコピーしました