CプロセスからJavaにバイトストリームを送信しているので、質問します。C側では、32ビット整数はLSBが最初のバイトで、MSBが4番目のバイトです。
だから私の質問は:Java側で、Cプロセスから送信されたバイトを読み取るとき、Java側のエンディアンは何ですか?
追加質問:Java側のエンディアンが送信されたエンディアンと異なる場合、どうすればそれらを変換できますか?
CプロセスからJavaにバイトストリームを送信しているので、質問します。C側では、32ビット整数はLSBが最初のバイトで、MSBが4番目のバイトです。
だから私の質問は:Java側で、Cプロセスから送信されたバイトを読み取るとき、Java側のエンディアンは何ですか?
追加質問:Java側のエンディアンが送信されたエンディアンと異なる場合、どうすればそれらを変換できますか?
回答:
とにかくJavaが使用するのと同じネットワークバイトオーダー(ビッグエンディアン)を使用します。Cのさまざまな翻訳者のman htonsを参照してください。
私はGoogleを介してここで偶然見つけ、Javaはビッグエンディアンであるという私の答えを得ました。
回答を読んで、バイトには確かにエンディアン順があることを指摘したいと思いますが、「メインストリーム」のマイクロプロセッサしか扱っていない場合は、Intel、Motorola、Zilogのすべてとしてこれに遭遇することはまずありません。彼らのUARTチップのシフト方向とバイトのMSBがあり2**7
、LSBが2**0
彼らのCPUにあることに同意しました(私はFORTRANの電力表記を使用して、これがどれほど古いかを強調しました:))。
私がこの問題に遭遇したのは、スペースシャトルのビットシリアルダウンリンクデータを20年以上前に$ 10KのインターフェイスハードウェアをMacコンピューターに交換したときです。NASA Techブリーフがずっと前に公開されています。table[0x01]=0x80
各バイトがビットストリームからシフトインされた後、ビットが反転された(など)256要素のルックアップテーブルを使用しました。
Javaには符号なし整数はありません。すべての整数は符号付きでビッグエンディアンです。
C側では、各バイトの先頭にLSB、左側にMSBがあります。
LSBを最下位ビットとして使用しているようですね。LSBは通常、最下位バイトを表します。 エンディアンはビットベースではなくバイトベースです。
符号なしバイトからJava整数に変換するには:
int i = (int) b & 0xFF;
バイト[]の符号なし32ビットリトルエンディアンからJava longに変換するには(私の頭の上から、テストされていません):
long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
Javaのintにいくつかのバイトを直接マップする(直接の非API)方法がないため、これがJavaの何かに影響を与える可能性はありません。
これまたは同様のことを行うすべてのAPIは動作をかなり正確に定義しているため、そのAPIのドキュメントを調べる必要があります。
私はバイトを1つずつ読み取り、それらを長い値に結合します。そうすることで、エンディアンを制御でき、通信プロセスは透過的です。
使用するプロトコルに適合する場合は、動作が非常に明確に定義されているDataInputStreamの使用を検討してください。
上記のように、Javaは「ビッグエンディアン」です。つまり、(少なくともIntel CPUで)メモリを調べると、intのMSBが左側にあります。符号ビットは、すべてのJava整数型のMSBにもあります。
「リトルエンディアン」システムによって格納されたバイナリファイルから4バイトの符号なし整数を読み取るには、Javaで少し調整が必要です。DataInputStreamのreadInt()はビッグエンディアン形式を想定しています。
以下は、4バイトの符号なし値(HexEditで01 00 00 00として表示)を値1の整数に読み取る例です。
// Declare an array of 4 shorts to hold the four unsigned bytes
short[] tempShort = new short[4];
for (int b = 0; b < 4; b++) {
tempShort[b] = (short)dIStream.readUnsignedByte();
}
int curVal = convToInt(tempShort);
// Pass an array of four shorts which convert from LSB first
public int convToInt(short[] sb)
{
int answer = sb[0];
answer += sb[1] << 8;
answer += sb[2] << 16;
answer += sb[3] << 24;
return answer;
}
java force indeed big endian:https : //docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11
byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array();
生産byte
、私のものの逆である配列C/C++
生成を。したがって、Java のビッグエンディアンは、実行時のデータでも有効になります。