• ベストアンサー

byte型のマイナスの扱いについて

COMポートを使用して通信をしようとしています。 制御コマンドを1byte区切りで送信するのですが、byte型で扱う際、-128~-1の扱いが思うようにいきません。 ウェブを検索して符号拡張など検討してみたのですが解決できませんでした。 いろいろやってみましたが、基本的には byte[] byteArray = {0x12,0x20,-0x80}; String str = new String(byteArray,0); BufferedWriter bw; bw.write(str); このようになっています。 0x12や0x20の送信は、信号を調べる機器にて正しく送信されていることが確認できたのですが、-0x80は予期せぬ値になってしまいます。 -0x80では、16進でC0,3Fなどになってしまいます。 二進で先頭に1がたっていることが原因なのでしょうか。。。 int型にしたり、byte型そのままで送ったり、0x40から左にビットシフトして(&ffも忘れずに)代入したりもしたのですが、結果は同じでした。 ご教授宜しくお願いします!

質問者が選んだベストアンサー

  • ベストアンサー
  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

こちらで実験してみました。 たしかに変な数値になります。 実際にどういう仕組でおかしくなっているのかはわかりません。 しかし、おそらく出力にWriterを使っているのが問題だろうと思われます。 Javaの出力には、OutputStream系列と、Writer系列があり、 バイナリデータはOutputStream、テキストファイルはWriterと、 使い分けをすることになっています。 Writer系列では、おそらく内部で1回Unicodeに変換されるので、 その過程でエラーが出たのだろうと思います。 見たところ、出力したいのはバイナリデータのようなので、 プログラム中でWriterを使っているところを OutputStreamに置き換えることをお勧めします。 もしそれが難しければ、OutputStreamとWriterをつなぐ OutputStreamWriterの使用も検討してみてください。 --------------------------- (たぶん正常に動くコード) byte[] byteArray = {0x12,0x20,-0x80}; try{ FileOutputStream fo = new FileOutputStream("test.out"); BufferedOutputStream bw = new BufferedOutputStream(fo); bw.write(byteArray, 0, 3); bw.flush(); }catch(Exception e){} -----------------------------

mitmit
質問者

お礼

ありがとうございます! 早速試してみたいと思います!!

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • deadlock
  • ベストアンサー率67% (59/87)
回答No.2

#1さんの仰るとおり、OutputStreamを使用することで解消されます。 予期しない値に変換される箇所は、Writerの内部ですね。 3Fは文字で言うと'?'あたります。順を追っていくと、 > byte[] byteArray = {0x12,0x20,-0x80}; この3つの値は、2行目のnew Stringでcharに変換されます。3つ目の文字は文字に変換できない値になります。(一文字目も見慣れない文字になりますが、サポート内のようですね) > String str = new String(byteArray,0); コンストラクタString(byte[], int)第一引数を2バイト目のビット列に、第二引数を1バイト目のビット列に使用してcharを作成します。APIにあるとおり、第一引数のバイト列はascii文字に使用可能な値をとる必要があります。 > BufferedWriter bw; > bw.write(str); writerがOutputStreamにバイト列として書き出す際に、文字コードの変換が行われます。この際、変換できない値はすべて'?'に置き換えられます。'?'がビット列になって送信されるので、相手には0x003Fという値が送信されることになります。 もう一度短く書くと、 new Stringで-0x80は文字として不正な値になる →writeで'?'に変換される →streamには'?'がビット列になったものが送信される →相手に0x00CFで届く という流れになります。

mitmit
質問者

お礼

本日意図するとおりに通信することができました。 ありがとうございました!!

すると、全ての回答が全文表示されます。

関連するQ&A