Java的二进制文件字节序转换

字节序指的是数据存储的顺序问题,分为Big-Endian和Little-Endian,Big-Endian指的是数据中的高位存储在存储器的低位,Little-Endian正好相反。Big-Endian也叫大头在前,Little-Endian叫做小头在前。
举例而言,有一个4字节的数据0x01020304,要存储在内存中或文件中编号0~3字节的位置,两种字节序的排列方式分别如下:
Big Endian
低地址                           高地址
----------------------------------------->
地址编号
|     0      |      1     |     2       |      3    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     01     |      02    |     03      |     04    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

低地址                           高地址
----------------------------------------->
地址编号
|     0      |      1     |     2       |      3    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     04     |      03    |     02      |     01    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

如果按照我们一般的书写习惯来说,Big-Endian似乎更好一点。
具体应用中是用big还是little就要取决于系统平台了。不同的CPU会有不同的情况,比如说x86架构的cpu使用的是little模式,而PowerPC则是big。C/C++语言对数据的处理取决于其运行的CPU,而Java则统一使用big模式。
如果单纯仅是使用Java的话也就不存在大小字节序的处理问题,但有时候Java程序可能还要使用到C/C++这类语言生成的数据,尤其是在我们常用x86环境下,两种语言的字节序就会出现不一致的问题,必须做一定的处理。
处理的方法很简单,就是把数据按字节前后调换一下就可以了。
在这里是将长度为len的数据转换成字节数组str[len],带入以下函数,如果原始数据是little,也就是big=false的情况下,函数将对数据进行高低位的调换,并返回。
publicstaticbyte[] ReversEndian(byte str[],int len, boolean big)
    {
       byte b;
       byte res[]=newbyte[len];
       for(int i=0;i<len;i++)
       {
           res[i]=str[i];          
       }
       if(big==false)
       {
           for(int i=0;i<len;i++)
           {
              b=str[i];
              res[len-i-1]=b;            
           }
       }     
       return res;
    }

假设现在我们需要从一个C/C++语言生成的二进制文件中读出一个float数据,可以如下处理。
//文件名
String fileName="file";
//float变量是4字节长
byte b[]=newbyte[4];
ByteBuffer bb;
File file=new File(fileName);
FileInputStream fis=new FileInputStream(file);
//从文件中读取一个4字节数据
fis.read(b);
//反转
b=ReversEndian(b,4,false);
//将字节数组还原成浮点数值
bb=ByteBuffer.wrap(b);
float value=bb.getFloat();

你可能感兴趣的:(java)