m-saitoh’s blog

SE・PGのフリーランスになったメモ

javaでファイル出力(SJIS)

javasjisファイル

UTF8でないファイル出力をする事になったのでメモ

public class OutputSjis {

    private final static byte CR = 0x0d; // 13
    private final static byte LF = 0x0a; // 10

    public static void main(String[] args) {

        this.output();

    }

    /**
     * sjisファイル出力処理<br />
     * 参考サイト
     * <li>http://ash.jp/java/stream.htm
     * <li>http://www.ne.jp/asahi/hishidama/home/tech/java/files.html
     */
    private void output() {
        // 出力先のディレクトリ。無ければ親を含めて作成する
        Path dir = Paths.get("C:/temp/work");
        // Path path = Paths.get("/export/home/users/foo/sjis"); // Solarisの構文
        // Path path = Paths.get("C:\\temp\\work\\sjis.txt"); // Windowの構文
        if (Files.notExists(dir)) {
            try {
                Files.createDirectories(dir);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 出力先のファイル
        Path path1 = dir.resolve("sjis1.txt");
        Path path2 = dir.resolve("sjis2.txt");
        Path path3 = dir.resolve("sjis3.txt");
        Path path4 = dir.resolve("sjis4.txt");

        File file1 = path1.toFile();
        File file2 = path2.toFile();

        // 仮データ作成
        List<String> dataList = new ArrayList<>();
        dataList.add("あいうえお");
        dataList.add("~"); // 良く文字化けするやつ
        dataList.add(" "); // MS932では変換出来ない文字(ソースファイルはUTF8である必要がある)
        dataList.add("かきくけこ");

        // 【パターン1】元データがByteで来る場合を想定
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file1))) {
            for (String data : dataList) {
                // 「MS932」はエイリアスで、正式名は「windows-31j」
                // 「SJIS」はエイリアスで、「Shift_JIS」が正式名
                byte[] bb = data.getBytes(Charset.forName("MS932"));
                bos.write(bb);
                bos.write(CR); // CR
                bos.write(LF); // LF
                bos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 【パターン2】元データがStringで来る場合を想定
        try (PrintWriter pw = new PrintWriter(
                new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2), Charset.forName("MS932"))))) {

            for (String data : dataList) {
                pw.println(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 【パターン3】パターン1は、java8ではこう書ける
        try (OutputStream os = Files.newOutputStream(path3)) {
            // StandardOpenOptionの指定無しは、CREATE・TRUNCATE_EXISTING・WRITEと同じ
            for (String data : dataList) {
                byte[] bb = data.getBytes(Charset.forName("MS932"));
                os.write(bb);
                os.write(CR); // CR
                os.write(LF); // LF
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 【パターン4】パターン2は、java8ではこう書ける
        // ただし、パターン2ではエンコード出来ない文字が?で出力されるのに対して、こっちはUnmappableCharacterExceptionが投げられる
        try (BufferedWriter bw = Files.newBufferedWriter(path4, Charset.forName("MS932"))) {
            for (String data : dataList) {
                bw.write(data);
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}