大小端转换

一、名词解释

首先解释一下大端模式和小端模式。

小端模式,也叫小端存储:

Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

大端模式,也叫大端存储:

Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

比如说数字1045037161

大端存储:

DEC:1045037161

低地址-------------------------->高地址

HEX: 0x3E 0x4A 0x00 0x69

BIN:00111110 01001010 00000000 01101001

小端存储:

DEC:1761626686

低地址-------------------------->高地址

HEX: 0x69 0x00 0x4A 0x3E

BIN:01101001 00000000 01001010 00111110

再举个例子,比如数字37

大端存储:

DEC:37

低地址-------------------------->高地址

HEX: 0x00 0x00 0x00 0x25

BIN:00000000 00000000 00000000 00100101

小端存储:

DEC:620756992

低地址-------------------------->高地址

HEX: 0x25 0x00 0x00 0x00

BIN:00100101 00000000 00000000 00000000

一个字节就是8bit,大小端就是一个字节正着存,一个字节反着存。这两种没有那种好还是不好,就是存储模式不同。但是人们熟悉的方式肯定是大端存储,37读出来就是37,如果是小端存储读出来就是620756992,完全不知道是什么了。

计算机存储是按照字节存储的,一个字节是8比特。但是如果数据比较大,一个字节存储不下,就需要多个字节存储。比如0x1122,也就是数字4386,就是占用了两个字节进行存储。那么0x11就是高位字节,0x22就是低位字节。而存储字节变多了之后,存储的可能性也就会变多了。为了保证数据存储和使用不出错,我们必须按照某种规范进行存储数据。比如0x1122,可以按照0x11 0x22的顺序进行存储(即大端存储),也可以按照0x22 0x11的循序进行存储(即小端模式)。这里就解释了上面的大小端定义。在一个独立的系统中,只要选择一个稳定的存储模式就可以保证系统内部不出错。但是如果和外部系统进行数据交换,则需要商定交换协议,如果两个系统存储方式不同,就涉及到大小端转换问题了。

C语言是小端存储,java都是大端存储。所以java要想读C语言生成的二进制文件,就需要大小端转换了。

二、大小端转换方式

大小端转换其实很简单,就是byte数组,把位置倒叙一下就可以了。自己写代码也就是一个循环,如下:

    /**
     * 切换大小端
     */
    public static byte[] changeBytesEndian(byte[] x){
        byte[] y = new byte[x.length];
        for (int i = 0; i < y.length; i++) {
            y[i] = x[y.length - i - 1];
        }
        return y;
    }

不过,比较正统的转换方式是使用ByteBuffer的order方法。

    /**
     * 将bytes转为大端数据,返回int
     * c存储二进制文件是用的小端存储,java都是大端存储,因此需要转换,此方法用于将数据转为大端存储,读出二进制文件
     * @param bytes
     * @return
     */
    private static int bytesToBigEndian(byte[] bytes) {
        return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt();
    }

    /**
     * 将bytes转为小端数据,返回int
     * c存储二进制文件是用的小端存储,java都是大端存储,因此需要转换,此方法用于将数据转为小端存储,写入二进制文件
     * @param bytes
     * @return
     */
    private static int bytesToLittleEndianInt(byte[] bytes){
        return ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getInt();
    }

当然,其他数据类型也是支持的。只是输入的bytes要自己按照位数写对,short是2位,int是4位,long是8位......基础知识就不多说了!

大小端转换_第1张图片

你可能感兴趣的:(java,c语言,开发语言)