はまった

仕事でプログラミングしていてもここまでデバッグに苦労したことはなかったくらい、時間と手間と頭を使ったデバッグをしていた。
対象は、先日マルチスレッド化したAppleAcriptの実行部分。
受信データが文字化けすることがあったのだ。曲名とかならエラーにならないが、日付の文字列で化けるとDate型に変換する前にInteger.parseInt()をするからNumberFormatExceptionが発生してしまう。
ソースを見ると原因はすぐにわかった。
byte配列のバッファでリードしているのだが、リードして、Stringオブジェクトに変換して、StringuBuffer(出力)にappendしていたのだ。
これでは、readの境界がマルチバイト文字の中に入った場合文字化けしてしまう。
対策お思いつくのは簡単だった。Stringオブジェクトにするのはすべてのreadが終わってから一度だけすれば言い訳で、それまではbyte配列のまま扱っておけばいい。
紙にアルゴリズムを書いて、リードバッファ、テンポラリバッファ、すべてのbyte列を保持する最終的なバッファを用意して結合までは成功していた。
しかし、呼び出し元に戻ると、スレッド内では存在する文字列がなくなってしまう。
原因は、パラメータのStringBufferに対してnewしていたことだった。
元々、呼び出し元で空の状態でnewしているから、appendしてやればよかった。
これで呼び出し元に取得文字列が戻るようになった。
結構、read後の配列操作でパフォーマンスが悪いかと思われる、書き直したいコードなのだが、それなりの速度で動いている。
他の部分の実装が先であろう。

コメント