技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

java:他環境向けのファイルを出力する(文字コード・改行コード指定)

javaは実行環境に応じてデフォルトの文字コード・改行コードでファイルを出力するようにコーディングすることができます。
そのことにより、実行環境毎でコーディングを変更せずとも、実行環境に合わせた文字コード・改行コードを採用することができます。
 
しかし、他の環境向けのファイルを出力する場合、実行環境のデフォルトの文字コード・改行コードが採用されると困ることがあります。
そのような場合は、FileOutputStreamクラスを用いれば、指定した文字コード・改行コードを採用することができます。
 
なお、FileWriterクラスを用いる場合は、setPropertyで実行環境のデフォルトを変更しても文字コードは変更できませんでした。
公式ドキュメント(https://docs.oracle.com/javase/jp/8/docs/api/java/io/FileWriter.html)では「文字ファイルを書き込むための簡易クラスです。このクラスのコンストラクタは、デフォルトの文字エンコーディングとデフォルトのbyteバッファのサイズが許容できることを前提としています。」と書かれており、まさにその通りの挙動となっています。
 
【テストコード】
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class FileOutputMain {

    public static void main(String args) throws IOException {

        // 開発環境のデフォルトを確認
        System.out.println("■開発環境のデフォルト");
        System.out.println("OS:"+System.getProperty("os.name"));
        System.out.println("文字コード:"+System.getProperty("file.encoding"));
            //
        System.out.print("改行コード(16進数):"); //0d0aは\r\nを指す
        char buf =
                new String(System.getProperty("line.separator")).toCharArray();
        for (char ch : buf) {
            String str = Integer.toHexString(ch);
            if(str.length() == 1){
                str = "0" + str;
            }
            System.out.print(str);
        }
        System.out.println();

        // ファイルに出力する文字列
        String record = "ほげ";

        // 改行コード定義
        String zero_d_zero_a = "\r\n";
        String zero_a = "\n";

        // FileWriterでファイル出力
        final FileWriter fw1 = new FileWriter("C:\\tmp\\test1.txt");
        fw1.write(record+System.getProperty("line.separator"));
        fw1.close();

        // FileWriterだと文字コードを変更できない(setPropertyも反映されず)
        System.setProperty("file.encoding","Shift-JIS");
        System.setProperty("line.separator","\n");
        final FileWriter fw2 = new FileWriter("C:\\tmp\\test2.txt");
        fw2.write(record+System.getProperty("line.separator"));
        fw2.close();
        System.setProperty("file.encoding","UTF-8");
        System.setProperty("line.separator","\r\n");

        // FileOutputStreamで文字コード・改行コードを指定(Shift-JIS,\r\n)
        PrintWriter pw1 = new PrintWriter(
                          new BufferedWriter(
                          new OutputStreamWriter(
                          new FileOutputStream
                            ("C:\\tmp\\test3.txt"),"Shift-JIS")));
        pw1.print(record+zero_d_zero_a);
        pw1.close();

        // FileOutputStreamで文字コード、改行コードを指定してファイル出力(UTF-8,\n)
        PrintWriter pw2 = new PrintWriter(
                          new BufferedWriter(
                          new OutputStreamWriter(
                          new FileOutputStream
                            ("C:\\tmp\\test4.txt"),"UTF-8")));
        pw2.print(record+zero_a);
        pw2.close();

    }
 
【標準出力】
■開発環境のデフォルト
OS:Windows 8.1
文字コードUTF-8
改行コード(16進数):0d0a
 
【ファイル出力結果】

f:id:akira2kun:20190624232550j:plain