java写二进制文件考虑一下字节顺

以前在Java写一些二进制格式的文件,就用DataOutputStream很方法,例如它的 writeInt,writeLong等,我今天在看一些代码的时候发现DataOutputStream在处理多字节的数字的时候,使用的是 BIG_ENDIAN(即将高位的字节放在内存地址的低地址上),相应的DataInputStream的读取方式也使用的是BIG_ENDIAN。
如果我是用C语言读取由DataOutputStream生成的文件,而平台正好是 LITTLE_ENDIAN,很可能会造成数据错误,除非在C程序中自己重新按照 BIG_ENDIAN的格式组装int或者long.
这样我们需要在写文件的时候就按照平台的字节顺来写,而ByteBuffer已经考虑到了这一点。
java.nio.ByteBuffer默认是BIG_ENDIAN(这可能和ByteBuffer主要用来做网络通讯有关),但是这个值是可以修改的。
比较使用DataOutputStream和ByteBuffer写文件的差异:
public static void main(String[] args) throws IOException {
        int _int = 12345678;
        ByteBuffer _nbuffer = ByteBuffer.allocate(4);
        _nbuffer.order(ByteOrder.nativeOrder());  //将新建的ByteBuffer设置为本机的字节顺
        _nbuffer.putInt(_int);
        _nbuffer.flip();


        FileOutputStream _fou = new FileOutputStream("test_dout.data");
        FileOutputStream _nfou = new FileOutputStream("test_nbuf.data");
        DataOutputStream _dou = new DataOutputStream(_fou);


        _dou.writeInt(_int);
        _dou.close();
       
        _nfou.write(_nbuffer.array());
        _nfou.close();
        System.out.println(ByteOrder.nativeOrder());
    }
执行上面的代码生成两个文件:
test_dout.data - 使用DataOutputStream生成的BIG_ENDIAN文件,
test_nbuf.data - 使用ByteBuffer生成的主机字节顺的文件(此处的主机字节顺为LITTLE_ENDIAN)
使用下面的C程序分别读取这两个文件:
#include <stdio.h>
int read_file(char* file);
main()
{
  char* dout = "test_dout.data";
  char* nbuf = "test_nbuf.data";
  printf("data in %s:%d\n",dout,read_file(dout));
  printf("data in %s:%d\n",nbuf,read_file(nbuf));
}
int read_file(char* file)
{
  FILE *fp;
  int dat[1];
  fp=fopen(file, "rb");
  fread(dat, sizeof(int), 1, fp);
  fclose(fp);
  return dat[0];
}
编译并执行:
gcc a.c
./a.out
data in test_dout.data:1315027968
data in test_nbuf.data:12345678
上面的C程序从test_dout.data取得的int数值是错误的,而从test_nbuf.data是正确的。
ByteBuffer不方便的地方在于它的大小不能自动扩展,但是也是可以解决的,比如MINA自己的ByteBuffer就支持自成扩展。
Java的生成二进制数据文件,应该要考虑一下字节顺的问题,以适应一些特殊的需求,比如多语言平台编程的情况。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值