こんばんは。関東では今日夜から雪が降るそうです。
風邪をひかないようにあったかくして休みましょう。
今日は文字化けの話です。
1.読んでいただきたい方
・Java初心者の方
・出力ファイルの文字化けに苦しんでいる方
・特にデフォルトエンコーディングがMS932の方は、僕の環境と同じなので共感できるかも知れません(調べ方は下記参照)
2.はじめに
前回の記事でも書いたのですが、僕はもともとvbscriptでファイルの読み書きをしていましたが、windows10から文字コードがUTF-8になり、文法も変わったのをきっかけにJavaで入出力のプログラムを作る事にしました。
どっこいこれが大苦戦・・。
自分なりにポイントをまとめておこうと思います。
3.ポイント
・自分の開発環境のデフォルトエンコーディングを理解する
・入力・出力の文字コードをきちんと指定する
###4.本日の作品
このようなプログラムを作成しました(utftest.java)。
デフォルトエンコーディングがMS932の方も、
以下のプログラムを実行すると、UTF-8→UTF-8のファイル入出力ができます!!
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
public class utftest{
public static void main(String args[]) throws IOException{
try{
File file = new File("K0040d.txt");
//BufferedReader br = new BufferedReader(new FileReader(file));
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
//FileOutputStreamで文字コード・改行コードを指定(UTF-8,\n)
PrintWriter fw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"),"UTF-8")));
String str = br.readLine();
while(str != null){
System.out.println(str);
fw.print(str + "\n");
str = br.readLine();
}
br.close();
fw.close();
}catch(FileNotFoundException e){
System.out.println(e);
}catch(IOException e){
System.out.println(e);
}
}
}
インプットデータ(K0040d.txt)は以下。
2020/03/20 xxx -100 あいうえお
###5.対応したこと
####5-1.自分の開発環境のデフォルトエンコーディングを理解する
以下を参照にしてみてください。
https://www.javadrive.jp/start/encoding/index1.html
MS932:Shift-Jis
UTF-8の場合は、UTF-8と出力されるようです。
ここで、多くの方がMS932になるようですが、この場合、UTF-8で出力する場合は、明確にUTF-8であることをプログラムに指定する必要が出てきます。
####5-2.入力・出力の文字コードをきちんと指定する
(1).入力処理
入力で使用したBufferedReaderクラスは、文字コードを指定できます。
(修正前)
BufferedReader br = new BufferedReader(new FileReader(file));
(修正後)
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
UTF-8→Shift-Jisにすれば、Shift-Jis型のファイルも読み込み可能です。
(2).出力処理
最初は、出力にfileWriterを使用していました。
javaでファイル出力、とgoogle検索して出てきた方法です。こんな具合ですね。
FileWriter fw = new FileWriter("test.txt",true);
しかし、FileWriterでは、出力先の文字コードを決める事ができない事が分かりました。
(https://docs.oracle.com/javase/jp/8/docs/api/java/io/FileWriter.html)
「文字ファイルを書き込むための簡易クラスです。このクラスのコンストラクタは、デフォルトの文字エンコーディングとデフォルトのbyteバッファのサイズが許容できることを前提としています。」とありました。
つまりデフォルトエンコーディングがShift-Jisの場合、出力にはUTF-8を使うことができない事になるという事と理解して、FileOutputStreamを使うようにしました。
//FileOutputStreamで文字コード・改行コードを指定(UTF-8,\n)
PrintWriter fw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"),"UTF-8")));
###6.感想
正直、ここまでファイル入出力でハマるとは思いませんでしたが、前進して嬉しいです。
汎用的なクラスでできること、できないことを把握しておいた方が良いことも分かりました。
これで色々遊べるぞ・・。
ではまた。