- PR -

Shift_JISコード変換について

1
投稿者投稿内容
みーちく
大ベテラン
会議室デビュー日: 2002/08/29
投稿数: 131
投稿日時: 2003-09-03 18:32
こんにちわ。みーちくです。

皆様、ご教授願います。
あるCSVファイルを読み込んで、読み込んだ文字列をShift_JISコードに変換し、
ファイルに書き込むというプログラムを作成致しました。
もともと、外字を使用しているファイルなのですが、Shift_JISコードに変換した
時に、フリーのバイナリエディタでは「0xEB 0x5D」というコードになっているのですが、
JavaからのShift_JISコードに変換した場合「0x3D 0x5D」というコードに変換
されました。
原因がわからず困っております。
皆様ご教授願います。

[環境]
Windows2000
java:1.4.1_01

コード:
import java.util.*;
import java.io.*;

class test3{
    public static void main(String[] args){
        final String encoding = "SJIS";
        
        BufferedReader fin;
        String ss             = "";
        String brain_name     = "";
        String brain_a_name = "";
        try{
            fin = new BufferedReader(new InputStreamReader(new FileInputStream("KY20030903110128.csv"), encoding));
            while ((ss = fin.readLine()) != null){
                StringTokenizer st = new StringTokenizer(ss, ",");
                brain_name         = st.nextToken();
                brain_a_name       = st.nextToken();
                if(brain_a_name.equals("") == false){
                    String a = dump_sjis(brain_a_name);
                    write_error(a);
                }
            }
            fin.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    private static String dump_sjis(String str){
        StringBuffer sb = new StringBuffer();
        try {
            byte[] sjis = str.getBytes("SJIS");
            sb.append("SJIS(" + str + "): ");
            for(int i=0; i<sjis.length; i++){
                sb.append("0x" + Integer.toHexString(sjis[i] & 0xff) + " ");
            }
        }catch (java.io.UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new String(sb);
    }
    private static void write_error(String cd){
        PrintWriter fout = null;
        try {
            fout = new PrintWriter(new BufferedWriter(new FileWriter("SJIS_dump.txt", true)));
            fout.println(cd);
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2003-09-03 20:34
「0xEB 0x5D」というコードは、文字が割り当てられていません。
しかも、"SJIS" の指定だと、0xEB は2バイトコードの開始とは見なされないようです。
したがって、このデータをReaderから読み込んだ時点でUnicodeに変換しようとして、
0xEB → Unicode に変換できないため、'?' に置き換えられてしまう。
0x5D → そのまま1文字として読まれる。

というわけで、「0x3F 0x5D」となってしまいます。

ちなみに"MS932"だと、いちおうは2バイトコードだと認識されますが、
0xEB 0x5D → Unicode に変換できないため、'?' に置き換えられてしまう。
ので、「0x3F」になってしまいます。



[ メッセージ編集済み 編集者: coasm 編集日時 2003-09-03 21:06 ]
みーちく
大ベテラン
会議室デビュー日: 2002/08/29
投稿数: 131
投稿日時: 2003-09-04 10:25
みーちくです。

coasmさん。
分かりやすい説明ありがとうございました。
引用:

「0xEB 0x5D」というコードは、文字が割り当てられていません。
しかも、"SJIS" の指定だと、0xEB は2バイトコードの開始とは見なされないようです。
したがって、このデータをReaderから読み込んだ時点でUnicodeに変換しようとして、
0xEB → Unicode に変換できないため、'?' に置き換えられてしまう。
0x5D → そのまま1文字として読まれる。
というわけで、「0x3F 0x5D」となってしまいます。


この解決策は何かあるのでしょうか?

CSVファイルの出力時に使用している外字表があるので、外字文字を
Shift_JISコードで調べて、「〓(ゲタ)」や「 ⇒ (株)」と
いう用に文字を変換し、DBに登録したいと考えております。

Javaではやはり無理なのでしょうか?
宜しく御願いいたします。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2003-09-04 13:28
いずれにしても、Unicodeに変換される前のバイト列の段階で処理しないといけませんので、

(1) encoding="ISO8859_1" を指定した Readerを使って読み込む。
1文字=1バイトとして読まれるので、バイト列と同様の処理が実現できる。

(2) FileInputStram からバイト列を読み込んで処理する。

(3) FileChannelを使って、バイト単位で処理する。

(4) 必要な変換を行うようなCharsetDecoderを作る。

といった手段が考えられます。
コーディングの簡単さという点では、(1)が一番楽ではないかと。
(考え方として一番汚いやり方ですが)

みーちく
大ベテラン
会議室デビュー日: 2002/08/29
投稿数: 131
投稿日時: 2003-09-04 15:31
みーちくです。

coasmさん。
返信ありがとうございました。
また、大変助かりました。

いろいろ方法があるみたいですね。
こちらでもテストしてみたいと思います。
また、ご報告します。

ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)