JAVA ,无法进行字节重新排序
JAVA , unable to Byte ReOrder
我是 Java 编程新手,我尝试编写此函数(调试)作为学习练习,但它不起作用,我不明白为什么:
函数
public static void ByteReOrder(){
byte[] byte_array_uid = new byte[] { (byte)0x3A, (byte)0x2B, (byte)0x07 };
out.println("UID ("+ByteOrder.nativeOrder()+"): " + HumanReprByteToHex(byte_array_uid));
if(Byte.nativeOrder() == ByteOrder.LITTLE_ENDIAN){
ByteBuffer byte_buffer_uid = ByteBuffer.wrap(byte_array_uid);
out.println("Default ByteOrder is LITTLE_ENDIAN, change for BIG_ENDIAN ...");
byte_buffer_uid.order(ByteOrder.BIG_ENDIAN);
byte[] byte_array_from_byte_buffer_uid = new byte[byte_buffer_uid.remaining()];
byte_buffer_uid.get(byte_array_from_byte_buffer_uid);
out.println("UID ("+byte_buffer_uid.order()+") : " + HumanReprByteToHex(byte_array_from_byte_buffer_uid));
}else{
out.println("UID (LITTLE_ENDIAN): " + HumanReprByteToHex(byte_array_uid));
}
}
输出
UID (LITTLE_ENDIAN): 0x3A 0x2B 0x07
Default ByteOrder is LITTLE_ENDIAN, change for BIG_ENDIAN ...
UID (BIG_ENDIAN) : 0x3A 0x2B 0x07
结果总是小尾数,但 byte_buffer_uid.order() 似乎是正确的,我阻止...
尝试结果
0x07 0x2B 0x3A
提前致谢。
来自 java 文档
This class defines methods for reading and writing values of all other primitive types, except boolean. Primitive values are translated to (or from) sequences of bytes according to the buffer's current byte order, which may be retrieved and modified via the order methods. Specific byte orders are represented by instances of the ByteOrder class. The initial order of a byte buffer is always BIG_ENDIAN.
意味着ByteBuffer(和Java)的默认值总是BIG_ENDIAN。这将影响基本类型(short、int、long、float 和 double)的 getter 和 setter 方法。
调用get(array)
或array()
只会得到字节数组的后备副本,不会反映任何顺序。
尝试比较 "put" 一些原始值之后的字节数组,在你放置不同的顺序之前和之后。
ByteBuffer bb = new ByteBuffer();
bb.order(ByteOrder.BIG_ENDIAN);
bb.putFloat(1234.123f);
byte[] bytesOne = bb.array();
bb.clear();
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putFloat(1234.123f);
byte[] bytesTwo = bb.array();
// compare betwee bytesOne and bytesTwo to see different byte ordering.
默认的 byteOrder()
已经是 BIG_ENDIAN 所以设置它甚至不会改变 ByteBuffer 本身。即使您要更改 byteOrder,这也只是关于如何 read/write 多字节值的设置。它不会改变单个字节的顺序,只会改变它们在执行多字节操作时的读取或写入方式。
public static void main(String[] args) {
byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8};
ByteBuffer bb = ByteBuffer.wrap(bytes);
print(bb.order(ByteOrder.BIG_ENDIAN));
print(bb.order(ByteOrder.LITTLE_ENDIAN));
}
private static void print(ByteBuffer bb) {
System.out.println("With " + bb.order() + " byte order");
for (int i = 0; i < bb.capacity(); i++)
System.out.println("byte " + i + ": " + bb.get(i));
for (int i = 0; i < bb.capacity() - 2; i++)
System.out.println("short " + i + ": " + Integer.toHexString(bb.getShort(i)));
for (int i = 0; i < bb.capacity() - 3; i++)
System.out.println("int " + i + ": " + Integer.toHexString(bb.getInt(i)));
}
打印
With BIG_ENDIAN byte order
byte 0: 1
byte 1: 2
byte 2: 3
byte 3: 4
byte 4: 5
byte 5: 6
byte 6: 7
byte 7: 8
short 0: 102
short 1: 203
short 2: 304
short 3: 405
short 4: 506
short 5: 607
int 0: 1020304
int 1: 2030405
int 2: 3040506
int 3: 4050607
int 4: 5060708
With LITTLE_ENDIAN byte order
byte 0: 1
byte 1: 2
byte 2: 3
byte 3: 4
byte 4: 5
byte 5: 6
byte 6: 7
byte 7: 8
short 0: 201
short 1: 302
short 2: 403
short 3: 504
short 4: 605
short 5: 706
int 0: 4030201
int 1: 5040302
int 2: 6050403
int 3: 7060504
int 4: 8070605
当您将 int、long 或 float 写入 ByteBuffer 时,它不知道您写入了这些类型,只知道您写入了字节。这意味着当您更改 ByteOrder 设置时,它无法更改基础数据,因为它不知道前 8 个字节是 double、两个 int、4 short 还是 8 个字节。
唯一能做到这一点的方法是当您读取具有原始类型的数据时。只有在这一点上,代码才会对字节顺序做一些事情。
顺便说一句,在某些机器上本机顺序是 BIG_ENDIAN。
我是 Java 编程新手,我尝试编写此函数(调试)作为学习练习,但它不起作用,我不明白为什么:
函数
public static void ByteReOrder(){
byte[] byte_array_uid = new byte[] { (byte)0x3A, (byte)0x2B, (byte)0x07 };
out.println("UID ("+ByteOrder.nativeOrder()+"): " + HumanReprByteToHex(byte_array_uid));
if(Byte.nativeOrder() == ByteOrder.LITTLE_ENDIAN){
ByteBuffer byte_buffer_uid = ByteBuffer.wrap(byte_array_uid);
out.println("Default ByteOrder is LITTLE_ENDIAN, change for BIG_ENDIAN ...");
byte_buffer_uid.order(ByteOrder.BIG_ENDIAN);
byte[] byte_array_from_byte_buffer_uid = new byte[byte_buffer_uid.remaining()];
byte_buffer_uid.get(byte_array_from_byte_buffer_uid);
out.println("UID ("+byte_buffer_uid.order()+") : " + HumanReprByteToHex(byte_array_from_byte_buffer_uid));
}else{
out.println("UID (LITTLE_ENDIAN): " + HumanReprByteToHex(byte_array_uid));
}
}
输出
UID (LITTLE_ENDIAN): 0x3A 0x2B 0x07
Default ByteOrder is LITTLE_ENDIAN, change for BIG_ENDIAN ...
UID (BIG_ENDIAN) : 0x3A 0x2B 0x07
结果总是小尾数,但 byte_buffer_uid.order() 似乎是正确的,我阻止...
尝试结果
0x07 0x2B 0x3A
提前致谢。
来自 java 文档
This class defines methods for reading and writing values of all other primitive types, except boolean. Primitive values are translated to (or from) sequences of bytes according to the buffer's current byte order, which may be retrieved and modified via the order methods. Specific byte orders are represented by instances of the ByteOrder class. The initial order of a byte buffer is always BIG_ENDIAN.
意味着ByteBuffer(和Java)的默认值总是BIG_ENDIAN。这将影响基本类型(short、int、long、float 和 double)的 getter 和 setter 方法。
调用get(array)
或array()
只会得到字节数组的后备副本,不会反映任何顺序。
尝试比较 "put" 一些原始值之后的字节数组,在你放置不同的顺序之前和之后。
ByteBuffer bb = new ByteBuffer();
bb.order(ByteOrder.BIG_ENDIAN);
bb.putFloat(1234.123f);
byte[] bytesOne = bb.array();
bb.clear();
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putFloat(1234.123f);
byte[] bytesTwo = bb.array();
// compare betwee bytesOne and bytesTwo to see different byte ordering.
默认的 byteOrder()
已经是 BIG_ENDIAN 所以设置它甚至不会改变 ByteBuffer 本身。即使您要更改 byteOrder,这也只是关于如何 read/write 多字节值的设置。它不会改变单个字节的顺序,只会改变它们在执行多字节操作时的读取或写入方式。
public static void main(String[] args) {
byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8};
ByteBuffer bb = ByteBuffer.wrap(bytes);
print(bb.order(ByteOrder.BIG_ENDIAN));
print(bb.order(ByteOrder.LITTLE_ENDIAN));
}
private static void print(ByteBuffer bb) {
System.out.println("With " + bb.order() + " byte order");
for (int i = 0; i < bb.capacity(); i++)
System.out.println("byte " + i + ": " + bb.get(i));
for (int i = 0; i < bb.capacity() - 2; i++)
System.out.println("short " + i + ": " + Integer.toHexString(bb.getShort(i)));
for (int i = 0; i < bb.capacity() - 3; i++)
System.out.println("int " + i + ": " + Integer.toHexString(bb.getInt(i)));
}
打印
With BIG_ENDIAN byte order
byte 0: 1
byte 1: 2
byte 2: 3
byte 3: 4
byte 4: 5
byte 5: 6
byte 6: 7
byte 7: 8
short 0: 102
short 1: 203
short 2: 304
short 3: 405
short 4: 506
short 5: 607
int 0: 1020304
int 1: 2030405
int 2: 3040506
int 3: 4050607
int 4: 5060708
With LITTLE_ENDIAN byte order
byte 0: 1
byte 1: 2
byte 2: 3
byte 3: 4
byte 4: 5
byte 5: 6
byte 6: 7
byte 7: 8
short 0: 201
short 1: 302
short 2: 403
short 3: 504
short 4: 605
short 5: 706
int 0: 4030201
int 1: 5040302
int 2: 6050403
int 3: 7060504
int 4: 8070605
当您将 int、long 或 float 写入 ByteBuffer 时,它不知道您写入了这些类型,只知道您写入了字节。这意味着当您更改 ByteOrder 设置时,它无法更改基础数据,因为它不知道前 8 个字节是 double、两个 int、4 short 还是 8 个字节。
唯一能做到这一点的方法是当您读取具有原始类型的数据时。只有在这一点上,代码才会对字节顺序做一些事情。
顺便说一句,在某些机器上本机顺序是 BIG_ENDIAN。