我想将一些数据存储到Java中的字节数组中。基本上只是数字,每个数字最多占用2个字节。
我想知道如何将整数转换为2字节长的字节数组,反之亦然。我发现有很多解决方案在使用Google搜索,但是大多数解决方案没有解释代码中会发生什么。我真的不了解很多变化的东西,所以我希望能得到一个基本的解释。
使用在java.nio命名空间中找到的类,尤其是ByteBuffer。。它可以为你完成所有工作。
java.nio
ByteBuffer
byte[] arr = { 0x00, 0x01 }; ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default short num = wrapped.getShort(); // 1 ByteBuffer dbuf = ByteBuffer.allocate(2); dbuf.putShort(num); byte[] bytes = dbuf.array(); // { 0, 1 }
byte[] toByteArray(int value) { return ByteBuffer.allocate(4).putInt(value).array(); } byte[] toByteArray(int value) { return new byte[] { (byte)(value >> 24), (byte)(value >> 16), (byte)(value >> 8), (byte)value }; } int fromByteArray(byte[] bytes) { return ByteBuffer.wrap(bytes).getInt(); } // packing an array of 4 bytes to an int, big endian, minimal parentheses // operator precedence: <<, &, | // when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right int fromByteArray(byte[] bytes) { return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF); } // packing an array of 4 bytes to an int, big endian, clean code int fromByteArray(byte[] bytes) { return ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16) | ((bytes[2] & 0xFF) << 8 ) | ((bytes[3] & 0xFF) << 0 ); }
将带符号的字节打包为一个int时,每个字节都需要屏蔽掉,因为由于算术提升规则(在JLS,转换和提升中所述),它被符号扩展为32位(而不是零扩展)。
Joshua Bloch和Neal Gafter在Java Puzzlers(“每个字节都有很大的乐趣”)中描述了一个与此有关的有趣难题。在将字节值与int值进行比较时,将字节符号扩展为int,然后将该值与另一个int进行比较
Joshua Bloch和Neal Gafter在Java Puzzlers
byte[] bytes = (…) if (bytes[0] == 0xFF) { // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255 }
请注意,所有数字类型都用Java签名,但char是16位无符号整数类型。