Java输出小端二进制文件

最近和C语言的系统有交互,需要给对方传输二进制文件,但C语言的文件默认是小端,而Java作为网络应用程序,默认是大端

因此需要在写入二进制文件的时候修改一下写入字节的顺序。

先看看普通写入

FileOutputStream fos = new FileOutputStream("D:/temp/test.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
DataOutputStream dos=new DataOutputStream(bos);

dos.writeShort(66);

dos.close();
bos.close();
fos.close();

用16进制编辑器打开文件可以看到内容为

00 42

然而C语言中的顺序是小端先行,即

42 00

查看DataOutputStream.writeShort源码,其实它也是将数值分解成8位二进制(1byte)写入

public final void writeShort(int v) throws IOException {
    out.write((v >>> 8) & 0xFF);
    out.write((v >>> 0) & 0xFF);
    incCount(2);
}

故我们可以手动写入byte数组,将目标数值手动转化为一个byte数组,于是我们写一个方法

// 小端输出模式
public static byte[] short2Bytes(short a) {
    byte[] result = new byte[] {
            (byte) (a & 0xFF),
            (byte) ((a >> 8) & 0xFF)
    };
    return result;
}

修改调用,将最开始的

dos.writeShort(66);

改为

dos.write(short2Bytes((short)66));

输出文件就是小端先行了。

上面例子是写入short。int也是同理,写一个方法手动将int转byte数组

// 小端输出模式
public static byte[] int2Bytes(int a) {
    byte[] result = new byte[] {
            (byte) (a & 0xFF),
            (byte) ((a >> 8) & 0xFF),
            (byte) ((a >> 16) & 0xFF),
            (byte) ((a >> 24) & 0xFF)
    };
    return result;
}

调用的时候将

dos.writeInt(66);

改为

dos.write(int2Bytes(66));

至于long,按照规律,相信读者自己可以写出来。

最后附上完整demo代码

package smallend;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class SmallEndTest {

    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("D:/temp/test.txt");
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        DataOutputStream dos=new DataOutputStream(bos);
        
        dos.writeShort(66); // 00 42
        dos.write(short2Bytes((short)66)); // 42 00
        
        dos.writeInt(66); // 00 00 00 42
        dos.write(int2Bytes(66)); // 42 00 00 00
        
        dos.close();
        bos.close();
        fos.close();

    }
    
    // 小端输出模式
    public static byte[] short2Bytes(short a) {
        byte[] result = new byte[] {
                (byte) (a & 0xFF),
                (byte) ((a >> 8) & 0xFF)
        };
        return result;
    }
    
    // 小端输出模式
    public static byte[] int2Bytes(int a) {
        byte[] result = new byte[] {
                (byte) (a & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 24) & 0xFF)
        };
        return result;
    }

}

吐槽一下:网上找了半天博客,方法内容一大堆,楞是不知道到底咋用【大概我领悟力太差】。最后还是自己弄出来了,特此记录一下。

上一篇:nRF52832-Bluefruit52学习之外设开发(1)-- MPU6050六轴模块


下一篇:数据结构Part5 图