2011年8月19日金曜日

テキストファイルのコード変換 その後

テキストファイルのコード変換 その後


以前テキストファイルのコード変換を書きましたが、過ちがありました。


そして、ここにも問題が有ることが判明しましたので、こっちに後日談を書きました。


入力用のテキストデータとして次の文字列を使用しました。
原文:つかいやすいといえます。


Shift_JISで変換すると正確にコード変換されます。
これをUTF-16で復号すると次のように変換されます。
UTF-16で復号後:苂芩芢苢芷芢苆芢芦苜芷腂


これだと、コード変換じゃなくって、中国語への翻訳ですな。
UTF-16を使うと、エラーが無く、変換ができてしまうのです。中国語に。


Charsetの順序を"UTF-8", "UTF-16", "Shift_JIS"にすると、UTF-16変換がエラー無く実行されるため、Shift_JIS変換が実行されません。このため、上記の不都合が発生してしまいました。


この問題を解決したプログラムを掲載しておきます。



public class CodeChangeActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        int iSize;
        File fSD, f;
        FileInputStream fs;
        byte[] ba;
        
        fSD = Environment.getExternalStorageDirectory();
        f = new File(fSD, "tyi.txt");
        ba = new byte[6000];
        try{
            fs = new FileInputStream(f);
            iSize = fs.read(ba, 0, 6000);
            fs.close();
            
        }
        catch(FileNotFoundException e){
            return;
        }
        catch(IOException e){
            return;
        }
        
        int i;
        Charset charset;
        CharsetDecoder d;
        CoderResult r;
        CharBuffer cb;
        ByteBuffer bb;
        String[] sCharset = 
        {"UTF-8", "Shift_JIS", "EUC-JP", "ISO-2022-JP", "UTF-16"};
        bb = ByteBuffer.wrap(ba);
        cb = null;
        for(i=0; i<sCharset.length; i++){
            if(Charset.isSupported(sCharset[i])==true){
                charset = Charset.forName(sCharset[i]);
                d = charset.newDecoder();
                cb = CharBuffer.allocate(iSize);
                r = d.decode(bb, cb, true);
                if(r.isError()==false) break;
                bb.rewind();
            }
        }
        String s;
        TextView tv;
        if(i>=sCharset.length){
            s = "have no charset";
        }
        else{
            cb.rewind();
            s = cb.toString();
        }
        tv = (TextView)findViewById(R.id.MyText);
        tv.setText(s);
    }
}

CharsetDecoder.decodeメソッドの長所は、コード変換エラーが発生した場合、その時点で実行を停止することです。

0 件のコメント:

コメントを投稿