プログラマ38の日記

主にプログラムメモです。

【Java/その他】テキストファイルで、utf8からshift_jis(CP932)への変換時に注意すること

テキストファイルなどutf8だと扱いづらく、shift_jisに変換したい時があります。

欲しいコマンドがみつからない時に、自分で作成するときの注意事項です。

 

結論として、utf8からshift_jisへの変換で、プログラムで工夫することで文字化けを回避できる文字があります。

 

そもそも utf8からshift_jisの変換はshift_jisよりutf8の方が文字が多いため、文字化けは回避できません。ですが、次の文字は次のようにマッピングが可能で文字化けを回避できます。

 

shift_jisで文字化けする文字 shift_jisで文字化けしない文字
表示 文字コード 表示 文字コード
¢ ¢
£ £
¬ ¬

※OSのバージョンでは変換しなくても文字化けしない場合があります。

 

Java文字コード変換プログラムを作成する場合に、上の変換を考慮する前と後では次のようになります。

 

[文字の変換を考慮する前]

    String in = "読込むファイル名";
    String out= "書込むファイル名";
    
    String readEncoding = "utf8";
    String writeEncoding= "Windows-31J";
    

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(in),readEncoding));
    
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out),writeEncoding));
    

    while(true){
      String line = br.readLine();
      
      if(line ==null){
        break;
      }

      bw.write(line);
      bw.newLine();

    }
    
    br.close();
    bw.close();

 [文字の変換を考慮した後]

    String in = "読込むファイル名";
    String out= "書込むファイル名";
    
    String readEncoding = "utf8";
    String writeEncoding= "Windows-31J";
    

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(in),readEncoding));
    
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out),writeEncoding));
    
    
    //ShiftJIS用に変換するマップ
    HashMap<Character, Character> conversion = new HashMap<Character, Character>();

        conversion.put('\u2212','\uFF0D' ); //− → -
        conversion.put('\u301C','\uFF5E' ); //〜 → ~
        conversion.put('\u00A2','\uFFE0' ); //¢ → ¢
        conversion.put('\u00A3','\uFFE1' ); //£ → £
        conversion.put('\u00AC','\uFFE2' ); //¬ → ¬
        conversion.put('\u2014','\u2015' ); //— → ―
        conversion.put('\u2016','\u2225' ); //‖ →∥
    
    
    while(true){
      String line = br.readLine();
      
      if(line ==null){
        break;
      }

      //文字化けする文字の変換
      for(char src : conversion.keySet()){
        line = line.replace(src, conversion.get(src));
      }
      bw.write(line + " ");
    }
    
    br.close();
    bw.close();

上のように工夫することで、shift_jisでも文字化けせずに済みます。

 

特に「〜」は、OracleDBからのデータ取得や、webでのデータ取得の中で、文字化けしてしまう文字コードとなっている時が多いなーと感じています。