- 締切済み
UTF-16LEにエンコード
テキストファイル(ASCII)をUTF-16LEに文字コード変換するプログラムを作成したいのですが、 期待通りの結果がえられません。 下記のプログラムに問題があればご教授下さい。 (文字数の関係でコメント文を省略しました。) -------------------- StringsInputFile=args[0]; StringsOutputFile=args[1]; CharsetutfCharset=Charset.forName("UTF-16LE"); CharsetEncoderencoder=utfCharset.newEncoder(); ByteBufferutfBytes=null; try{ FileInputStreaminput=newFileInputStream(sInput); FileOutputStreamoutput=newFileOutputStream(sOutput); bytebuf[]=newbyte[256]; intlen; while((len=input.read(buf))!=-1){ ByteBufferunicodeBytes=ByteBuffer.wrap(buf); try{ utfBytes=encoder.encode(unicodeBytes.asCharBuffer()); } catch(CharacterCodingExceptione){ System.out.println("EncodeError!!["+e.getMessage()+"]"); continue; } output.write(utfBytes.array(),0,len); } output.flush(); output.close(); input.close(); }catch(FileNotFoundExceptione){ }catch(IOExceptione){ } return; } -------------------- 入力ファイルの中身は[TEST]と入力されています。 上記プログラムで得られた結果(出力ファイル) をバイナリエディタで確認すると 期待結果は [5400450053005400] なのですが、 [45545453](テキスト表示すると[ETTS]) となってしまいます。 できれば、BOM(FFFE)も先頭に付加したいです。 以上、宜しくお願い致します。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- UKY
- ベストアンサー率50% (604/1207)
> unicodeBytes.asCharBuffer() ByteBuffer を CharBuffer に変換したいんでしょうが、これではうまくいきません。 これは 2n バイトの ByteBuffer を 2 バイトずつ区切って n 文字の CharBuffer に変換せよという意味になります。 そもそも元のファイルから読み取ったデータをそのままむりやり文字に変換しようとしているのが誤りです。 元のファイルは ASCII でエンコーディングされているのですから、まずデータを ASCII バイト列から文字列に変換 (デコード) した上でそれを UTF-16 バイト列に変換 (エンコード) しなくてはなりません。 デコードの仕方はエンコードの仕方と似ているので調べればすぐ分かるでしょう。
- T0ngT0ng
- ベストアンサー率40% (8/20)
#1です 補足しときますと、元々のソースのほうは変換元がASCII であるために失敗しているんだと思います。 CharsetEncoderのAPIには "16 ビット Unicode 文字のシーケンスを特定の文字 セットで表現されたバイトシーケンスに変換する エンジンです。" とありますので、ASCII文字列をUnicode(Big Endian) だと思って変換しちゃうんでしょうね。
お礼
お礼が遅くなり申し訳ありません。 大変参考になりました。 ありがとうございました。
- T0ngT0ng
- ベストアンサー率40% (8/20)
OutputStreamWriterでエンコード指定しちゃうのが楽そうです。 (いずれにしても BOMは直接書かないとだめそうですが) 簡単には以下のようになりますか・・・ FileOutputStream fos = new FileOutputStream("./test.txt"); byte[] BOM={(byte)0xFF,(byte)0xFE}; fos.write(BOM); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-16LE"); osw.write("TEST"); osw.close();
お礼
お礼が遅くなり申し訳ありません。 まさにピンポイントのご回答でした。 ありがとうございました。
お礼
回答ありがとうございます。 大変参考になりました。