Categories: Java

【Java入門】ファイルの文字コードをSJISとUTF-8で相互変換する方法

この記事では、UTF-8のファイルをSJISに変換する方法と、SJISのファイルをUTF-8に変換する方法について解説しています。

SJISとMS932の違い

MS932はSJISの拡張版です。
Javaの世界ではSJISのファイルはMS932として扱います。
単にSJISと指定してしまうと文字化けする文字が出てくるので、JavaでSJISのファイルを扱いたい場合は、MS932と記述しておけばOKです。

UTF-8のファイルをSJISに変換する方法

入力ファイルの内容とエンコードは以下のとおりです。
charset=utf-8になっている場合、このファイルがUTF-8であることを示します。

user01@DESKTOP-AQBVPOG MINGW64 /c/workspace/result
$ file -i input_utf8.txt
input_utf8.txt: text/plain; charset=utf-8

user01@DESKTOP-AQBVPOG MINGW64 /c/workspace/result
$ cat input_utf8.txt
apple
りんご
林檎

Javaのコードは以下のとおりです。
UTF-8のファイルである「input_utf8.txt」をSJISに変換し、「out_SJIS.txt」に出力します。

java

// エンコードしたいファイルのパス
String targetFilePath = "C:\\workspace\\result\\input_utf8.txt";

// ファイルの内容をbyteに変換する
byte[] data = Files.readAllBytes(Paths.get(targetFilePath));

// 出力先パス
String outPutSJIS = "C:\\workspace\\result\\out_SJIS.txt";
String outPutUTF8 = "C:\\workspace\\result\\out_UTF8.txt";

// ファイル出力(SJIS)
try(FileOutputStream fos = new FileOutputStream(outPutSJIS);
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	OutputStreamWriter osw = new OutputStreamWriter(bos, "MS932");){

	osw.write(new String(data, "UTF-8"));
}

// ファイル出力(UTF-8)
try(FileOutputStream fos = new FileOutputStream(outPutUTF8);
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	OutputStreamWriter osw = new OutputStreamWriter(bos, "UTF-8");){

	osw.write(new String(data, "UTF-8"));
}

解説

SJISのファイルを作りたいわけですので、以下のようにOutputStreamWriterにはMS932を指定します。

OutputStreamWriter osw = new OutputStreamWriter(bos, "MS932");

元ファイルはUTF-8で書かれていますので、書き込み時も以下のようにUTF-8を指定します。

osw.write(new String(data, "UTF-8"));

SJISのファイルをUTF-8に変換する方法

入力ファイルのエンコードは以下のとおりです。
charset=unknown-8bitになっている場合、このファイルがSJISであることを示します。

$ file -i input_sjis.txt
input_sjis.txt: text/plain; charset=unknown-8bit

Javaのコードは以下のとおりです。
SJISのファイルである「input_sjis.txt」をUTF-8に変換し、「out_UTF8.txt」に出力します。

java

// エンコードしたいファイルのパス
String targetFilePath = "C:\\workspace\\result\\input_sjis.txt";

// ファイルの内容をbyteに変換する
byte[] data = Files.readAllBytes(Paths.get(targetFilePath));

// 出力先パス
String outPutSJIS = "C:\\workspace\\result\\out_SJIS.txt";
String outPutUTF8 = "C:\\workspace\\result\\out_UTF8.txt";

// ファイル出力(SJIS)
try(FileOutputStream fos = new FileOutputStream(outPutSJIS);
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	OutputStreamWriter osw = new OutputStreamWriter(bos, "MS932");){
	osw.write(new String(data, "MS932"));
}

// ファイル出力(UTF-8)
try(FileOutputStream fos = new FileOutputStream(outPutUTF8);
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	OutputStreamWriter osw = new OutputStreamWriter(bos, "UTF-8");){
	osw.write(new String(data, "MS932"));
}

解説

UTF-8のファイルを作りたいわけですので、以下のようにOutputStreamWriterにはUTF-8を指定します。

OutputStreamWriter osw = new OutputStreamWriter(bos, "UTF-8");

元ファイルはSJISで書かれていますので、書き込み時も以下のようにMS932を指定します。

osw.write(new String(data, "MS932"));

OutofMemoryを発生させないために

前述まではFiles.readAllBytesでinputファイルの読み込みを行っていました。
この書き方の場合は、読み込むファイルのサイズが大きいとOutfoMemoryが発生するおそれがあります。これを回避するためにはバイト単位に読み込めばいいので、以下のように記述します。

Java

public static void main(String[] args) throws IOException {

    String before = "MS932";
    String after = "UTF-8";

    Path input = Paths.get("C:\\workspace\\test\\100MBms932.txt");
    Path output = Paths.get("C:\\workspace\\test\\resultUTF8.txt");

    //読み込み用ファイルを開く
    try(BufferedReader is = Files.newBufferedReader(input,Charset.forName(before));

        //ここから「書き込み用ファイル」
        FileOutputStream fos = new FileOutputStream(output.toFile());
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        OutputStreamWriter osw = new OutputStreamWriter(bos, after);){

		String str = null;
		while ((str = is.readLine()) != null) {
		    byte[] b = str.getBytes(before);
		    osw.write(new String(b, before));
		}

    } catch (IOException e) {
        e.printStackTrace();
    }
}

解説

このコードの重要な処理は以下の部分です。

Java

String str = null;
while ((str = is.readLine()) != null) {
    byte[] b = str.getBytes(before);
    osw.write(new String(b, before));
}

is.readLine()を用いると1行分がString型で取得できます。
これをbyte[] b = str.getBytes(before);で元の文字コードでバイト値を得ます。
そしてosw.write(new String(b, before));に元の文字コードで書き込みます。


以上で記事の解説はお終い!

もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!

issiki_wp