以前、こんなエントリを書きました。
Javaでbyte配列から、別のプリミティブ型に変換する
http://d.hatena.ne.jp/Kazuhira/20130512/1368368205
が、書き方がよくなかったみたい(?)で、NIOのByteBufferを使って変換しているところを見つけられていない方がいらっしゃったので、別にまとめることにしました。
すべて、NIOのByteBufferを使用します。
プリミティブ型→byte配列への変換
ここでは、long型からbyte配列への変換を行ってみます。longは8バイトなので、ByteBuffer#allocateで8バイト確保します。
ByteBuffer buffer = ByteBuffer.allocate(8); buffer.putLong(123456789L); for (byte b : buffer.array()) { System.out.print(b & 0xff); System.out.print(" "); } // 0 0 0 0 7 91 205 21
あとは、ByteBuffer#putLongした後にByteBuffer#arrayを呼び出すと、byte配列表現となった値が取得できます。
ちなみに、嬉しいかどうかは別にしてputLongは自分自身を返すので、全部繋げて書くこともできます。
ByteBuffer.allocate(8).putLong(123456789L).array();
まあ、せめてallocateで切りましょうか…。
byte配列→プリミティブ型への変換
今度は、byte配列からlongへの変換を行ってみます。先ほどのlong→byte配列の結果を参考に、long値のbyte表現を用意します。
byte[] bytes = {0, 0, 0, 0, (byte) 7, (byte) 91, (byte) 205, (byte) 21};
あとは、ByteBuffer#wrapしてgetLongしてください。
System.out.println(ByteBuffer.wrap(bytes).getLong()); // => 123456789
ここでは、longを使いましたが、他にもchar、double、float、int、short、もちろんbyteもあります。booleanはありませんが。
ちなみに、このオペレーションで扱われる…というより、ByteBufferのバイトオーダーの初期値はビッグエンディアンです。
リトルエンディアンで扱いたいのですが…
ではリトルエンディアンで扱う場合はどうするかというと、java.nio.ByteOrderを利用します。
先ほどのlong値のデータを、リトルエンディアンで用意します。
byte[] bytes = {(byte) 21, (byte) 205, (byte) 91, (byte) 7, 0, 0, 0, 0};
ByteBuffer#putLongした後で、ByteBuffer#orderでバイトオーダーをリトルエンディアンに変更します。
ByteBuffer buf = ByteBuffer.wrap(bytes);
buf.order(ByteOrder.LITTLE_ENDIAN);
System.out.println(buf.getLong()); // => 123456789
これで、無事リトルエンディアンのbyte配列もlongに戻せました。
嬉しいかどうかはさておき、こちらも1行で書けます。
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong();
オマケ
特に単一の値にこだわらず、連続した値も普通に扱えるのでいろいろやってみましょう。
たとえば、intを3つ分確保して、byte配列に一気に変換。
ByteBuffer buf = ByteBuffer.allocate(12); // int 3つ分 buf.putInt(12345); buf.putInt(45678); buf.putInt(78901); for (byte b : buf.array()) { System.out.print(b & 0xff); System.out.print(" "); } // 0 0 48 57 0 0 178 110 0 1 52 53
得られたbyte値から、int3つに戻します。
byte[] binary = {0, 0, (byte) 48, (byte) 57, 0, 0, (byte) 178, (byte) 110, 0, (byte) 1, (byte) 52, (byte) 53}; ByteBuffer buffer = ByteBuffer.wrap(binary); System.out.println(buffer.getInt()); // 12345 System.out.println(buffer.getInt()); // 45678 System.out.println(buffer.getInt()); // 78901
もしくは、こんな感じで表示?
byte[] binary = {0, 0, (byte) 48, (byte) 57, 0, 0, (byte) 178, (byte) 110, 0, (byte) 1, (byte) 52, (byte) 53}; ByteBuffer buffer = ByteBuffer.wrap(binary); for (int i = buffer.position(); i < buffer.capacity() / 4; i++) { System.out.println(buffer.getInt()); }