JAVA,无法Byte ReOrder

时间:2015-09-01 07:16:01

标签: java endianness

我是Java编程新手,我尝试将此函数(debug)编写为学习练习,但它不起作用,我不明白为什么:

功能

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

结果总是在LITTLE ENDIAN中,但 byte_buffer_uid.order()似乎是正确的,我阻止......

尝试结果

0x07 0x2B 0x3A

提前谢谢。

2 个答案:

答案 0 :(得分:2)

来自java doc

  

此类定义了读取和写入除boolean之外的所有其他基本类型的值的方法。根据缓冲器的当前字节顺序将原始值转换为(或来自)字节序列,其可以通过顺序方法检索和修改。特定的字节顺序由ByteOrder类的实例表示。字节缓冲区的初始顺序始终为BIG_ENDIAN。

表示ByteBuffer(和Java)的默认值始终为BIG_ENDIAN。这将影响原始类型的getter和setter方法(short,int,long,float和double)。

仅调用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.

答案 1 :(得分:2)

默认byteOrder()已经是BIG_ENDIAN,因此设置它甚至不会更改ByteBuffer本身。即使你要改变byteOrder,这只是一个关于如何读/写多字节值的设置。它不会改变单个字节的顺序,只会在执行多字节操作时读取或写入它们。

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

当你向ByteBuffer写一个int,long或float时,它不知道你写了这些类型,只写了你写的字节。这意味着当您更改ByteOrder设置时,它无法更改基础数据,因为它不知道前8个字节是双精度,两个整数,四个短整数或八个字节。

这样做的唯一方法就是用原始类型读取数据。只有在这一点上,代码才会对字节的顺序做一些事情。

BTW某些机器上的本机订单是BIG_ENDIAN。