- PR -

byte配列の文字コード置換

投稿者投稿内容
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2007-06-21 17:31
引用:

未定義でした。使われていない0x86○○が使われてました。聞いてみたところ、そのデータは外字らしく、それがちゃんと表示できていないんだそうです。



なるほど。では、やはり置換するのが良さそうですね。

元のデータには文字「?」は含まれていますか?
含まれていないなら、数行の簡単なコードで置換できます。
含まれているなら、あしゅさんが示した方法など、ちょっと面倒になります。
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2007-06-21 17:38
本当に 0x86** だけが問題なら、byte[] で読んで 0x86 0x** を 0x81 0x45 に置換して byte[] で出力すればいいだけですけどね。
bonif
常連さん
会議室デビュー日: 2007/05/25
投稿数: 33
投稿日時: 2007-06-21 17:55
残念ながら、?が入っていました。

スフレさんのおっしゃっている方法でやっていたのですが、それでも直らない箇所が多々ありまして、そこも変換するように修正してみたのですが、全然直らなくて・・・・。

mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-06-21 18:03
こちらに書き込みますか。

なんだか、結果だけ見て「だめだった」と言っているように見えるんですが。
置換前後のバイト配列を表示してみるなりして、ちゃんと期待した値であり、
期待どおり置換されているかとか、見てみましたか?

こういったものは、途中経過を確認するようにしないと、なかなか直りませんよ。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-21 18:10
DBの中にあるデータかと思えばファイルから入力だったり、
もっと前提条件をきちんと整理して書いた方がいいんじゃないかと。

#そういえば前に関連しそうな質問に答えたことあるって今頃気付いたり。。

前に私が答えた通りに作っているのだとすれば、
Readerは使えないはずなのでバイト指向のまま行単位に分解して、
それをUnicodeに変換する時にフィルタをかけるだけなはずです。

でも、配列の扱い方すら難儀する状態だと厳しいかもしれませんね。

#さっきのコードがつっこみどころ多すぎで手を付けられなかった・・・。

ついでに、WIndowsで作ったファイルをShift_JISで読み込むと
いくつかの記号が化けるので、Windows-31Jとするのが正解です。
bonif
常連さん
会議室デビュー日: 2007/05/25
投稿数: 33
投稿日時: 2007-06-21 18:31
>mioさん
わざわざ移動していただいて、すみません。

変換前の文字列と変換後の文字列のバイトの比較は、やってます。
変換前のCSV・変換後の出力テキスト・バイト修正無しの出力テキストを比較してます。
今までの作業で一部期待通りの動作ができるようになり、その半分ほどが全然予想外の動きをしたりしてました・・・。

>あしゅさん
ややこしい書き方ですみませんでした。
言い訳がましく聞こえるかもしれませんが、Javaはほとんど独学で、今の職場で教えてくれる人が居ないんです。新卒1年目なんですけど、プログラマーで入ったのに出向先でSEの仕事させられたり・・・。
関係ない書き込みですみません。

とりあえず、あしゅさんのおっしゃる方法でやってみたいと思います。
bonif
常連さん
会議室デビュー日: 2007/05/25
投稿数: 33
投稿日時: 2007-06-26 12:17
経過報告です。
あれから少し仕様を変更しまして、CSVを読み込んでデータベースに格納するという手順に「CSVのバイトデータを参照・変換を行う」という操作を付け加えることにしました。
それによって現在のシステムへの修正が少なく済むと思ったからです。

というわけで、CSVをシフトJISで読み込んでシフトJISで書き出すというプログラムを考えました。

File f=new File("DATA.csv");
FileInputStream fin=new FileInputStream(f);
int len = (int)f.length();
byte[] data = new byte[len];
fin.read(data);
fin.close();

Charset charset = Charset.forName("SJIS");
CharsetDecoder decoder = charset.newDecoder();
decoder.replaceWith("・");
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
ByteBuffer bb1=ByteBuffer.wrap(data);
CharBuffer cb = decoder.decode(bb1);
CharsetEncoder encoder = charset.newEncoder();
encoder.replaceWith(new String("・").getBytes());
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
ByteBuffer bb2 = encoder.encode(cb);
byte[] outdata = bb2.array();

File f2 = new File("outputDATA.csv");
FileOutputStream fo = new FileOutputStream(f2);
fo.write(outdata);
fo.close();

以前あしゅさんに教えて頂いたCharsetEncoderとCharsetDecoderを使い、onUnmappableCharactorメソッドを用いて割り当てられてない文字の置換を行っているのですが、まだ文字化けをしています。

バイナリエディタで見てみたところ、領域外の文字のLeading Byteしか置換されていないようです。
後続のByteデータも変換させるには、どうすればよいのでしょうか。

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