web-dev-qa-db-ja.com

Java 4バイトをintに変換

この文書化された解決策 ここ はまだ解決策ですか、それとも4バイトからintを取得する他の方法はありますか?

ありがとうございました。

編集:ソケットからbyte []を取得しています。

編集:int recvMsgSize = in.read(Data, 0, BufferSize); recvMsgSizeが-1の場合、接続が切断されたことがわかります。

inputStreamの代わりにDataInputStreamを使用しているときにこれを検出するにはどうすればよいですか?

ありがとう。

編集:正しい答えを受け入れることに関してヨーヨーであることをお詫びします。しかし、mihiの更新された最終応答の後、メソッドはしっかりしていて、拡張コーディングを削減しているように見えます。私の意見では、ベストプラクティスです。

14
iTEgg

これらの4バイトをどこから取得するかに応じて:

http://docs.Oracle.com/javase/7/docs/api/Java/io/DataInput.html#readInt()

http://docs.Oracle.com/javase/7/docs/api/Java/nio/ByteBuffer.html#getInt(int)

もちろん手動で行うこともできますが、ほとんどの場合、それらの1つを使用する方が簡単です(たとえば、多数のバイトを含むバイト配列を変換する必要がある場合は、DataInputStreamの周りにByteArrayInputStreamを使用することをお勧めします)。

Edit:エンディアンを変更する必要がある場合は、ByteBufferを使用するか、バイトを自分で反転するか、DataInputとして自分で変換する必要があります。エンディアンの変更はサポートしていません。

Edit2:ソケット入力ストリームからそれらを取得するとき、それをDataInputStreamにラップし、あらゆる種類のデータの読み取りに使用します。特にInputStream.read(byte [])はバイト配列全体を埋めることを保証しないので... DataInputStream.readFullyはそうします。

DataInputStream in = new DataInputStream(socket.getInputStream());
byte aByte = in.readByte();
int anInt = in.readInt();
int anotherInt = in.readInt();
short andAShort = in.readShort(); // 11 bytes read :-)
byte[] lotOfBytes = new byte[anInt];
in.readFully(lotOfBytes);

Edit3:ストリームから複数回読み取る場合、停止した場所から読み取りを続行します。 e。 aByteはバイト0、anIntはバイト1〜4、anotherIntはバイト5〜8などになります。readFullyはその後読み取りを行い、lotOfbytesを読み取るまでブロックします。

ストリームが停止すると(接続が切断されると)、-1ではなくEOFExceptionが取得されるため、-1を取得すると、intは実際には-1になります。

バイトをまったく解析したくない場合は、それらをスキップ()できます。 DataInputStreamでは1バイトを2つの異なる方法で解析することはできません(つまり、最初にバイト0から3のintを読み取り、次にバイト2から5のintを読み取ります)が、通常は必要ありません。

例:

// read messages (length + data) until the stream ends:
while (true) {
int messageLength;
try {
    messageLength = in.readInt(); // bytes 0 to 3
} catch (EOFException ex) {
    // connection dropped, so handle it, for example
    return;
}
byte[] message = new byte[messageLength];
in.readFully(message);
// do something with the message.
}
// all messages handled.

これがあなたの追加の質問に答えることを願っています。

8
mihi

拡大変換と数値昇格には細心の注意を払う必要がありますが、以下のコードは4byteintに変換します。

    byte b1 = -1;
    byte b2 = -2;
    byte b3 = -3;
    byte b4 = -4;
    int i = ((0xFF & b1) << 24) | ((0xFF & b2) << 16) |
            ((0xFF & b3) << 8) | (0xFF & b4);
    System.out.println(Integer.toHexString(i)); // prints "fffefdfc"

も参照してください

  • バイトを16進数に変換するJavaコード
    • & 0xFFでマスクする必要性に注意してください-すべての算術演算はbyte(またはint)に昇格するため、longを使用している場合は、おそらくこれを多く行うことになります。
17

それらがすでにbyte[]配列にある場合は、次を使用できます。

int result = ByteBuffer.wrap(bytes).getInt();

または、クラスパスにGoogleの guava-libraries がある場合は、ショートカットがあります。

int result = Ints.fromByteArray(array);

これには、他のタイプ(Longs.fromByteArrayShorts.fromByteArrayなど)にも同様に優れたAPIがあるという利点があります。

16
Cowan