先日、Oracleから取得した文字列を Shift_JIS に変換したところ、外字だけ文字化けしました。 調べてみると、いわゆる「Shift_JIS」運用でも、実際は MS932(Windows-31J)前提のケースがあるとわかったので、備忘録として残します。
忙しい人向け
Shift_JIS で変換できない文字を含んでいたのが原因でした。 Java側で文字コード指定を Shift_JIS から MS932 に変更したら解消しました。
問題発生時のファイル構成(例)
sample-project/
└─ src/main/java/com/example/charset/Main.java
発生環境
- Java: 11
- DB: Oracle
- 事象: Oracleから取得した文字列をCSV向けにShift_JIS変換すると、一部文字が
?になる
1. 症状
今回の再現文字列は ㈱あいティーブログ です。 ㈱ が Shift_JIS では変換できず、? に置換されました。
import java.nio.charset.Charset;
public class Main {
public static void main(String[] args) {
String sample = "㈱あいティーブログ";
Charset sjis = Charset.forName("Shift_JIS");
Charset ms932 = Charset.forName("MS932");
System.out.println(new String(sample.getBytes(sjis), sjis));
System.out.println(new String(sample.getBytes(ms932), ms932));
}
}
実行結果(例)
?あいティーブログ
㈱あいティーブログ
2. 原因
Shift_JISとMS932は同じではなく、文字集合に差があるShift_JISで表現できない文字は、変換時に?へ置換される- 連携先が「Shift_JIS」と書いていても、実装としては
MS932前提のことがある
3. 対処法
変換時の指定文字コードを MS932 に変更します。
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
String body = "会社名\n㈱あいティーブログ";
Charset charset = Charset.forName("MS932");
Files.writeString(Path.of("output.csv"), body, charset);
必要であれば、CharsetEncoder で CodingErrorAction.REPORT を指定し、変換不能文字を例外として検知すると運用しやすくなります。
4. まとめ
Javaで日本語ファイル連携をするときは、「Shift_JIS」という表記だけを鵜呑みにしないのが大事でした。 文字化けが起きたら、まず MS932 指定での再現確認をしてみるのが早いです。


コメント