Java中的Big(Little)-endian问题的一种解决方法

http://blog.sina.com.cn/s/blog_d0bb1ceb0102v5gu.html
 
Java二进制文件中的所有东西都以big-endian形式存在,高字节优先,这有时被称为网络顺序。这是一个好的消息,意味着如果你只使用 Java。所有文件在所有平台(Mac,PC,Solaris等)上按同样的方式进行处理。可以自由地交换二进制数据,以电子形式在Internet上, 或在软盘上,而无需考虑endian问题。
 
    存在的问题是当你与那些不是使用Java编写的程序交换数据文件时,会存在一些问题。因为这些程序使用的是 little-endian顺序,通常是在PC上使用的C语言。有些平台内部使用big-endian字节顺序(Mac,IBM390);有些平台使用 little-endian字节顺序(Intel)。Java对用户隐瞒了endian问题。

解决方式可以采用:

 
重写提供输入文件的输出程序。它可以直接输出big-endian字节流DataOutputStream或者字符DataOutputSream格式。 
写一个独立的翻译程序,读和排列字节。可以用任何语言编写。
 
以字节形式读数据,并重新安排它们。
还有一种方式是自己编写函数进行数据格式的转化。
 
打开RandomAccessFile的源代码,发现数据处理的代码如下:
 
public final short readShort() throws IOException {  
     int ch1 = this.read();  
     int ch2 = this.read();  
     if ((ch1 | ch2) < 0)  
         throw new EOFException();  
     return (short)((ch1 << 8) (ch2 << 0))
  }
简单明了,一目了然,因此重写输入输出程序是最简单的方法。由于这里的readShort是final的,因此采用由RandomAccessFile派生的方法,建立的新类如下:
import java.io.*;
public class MyRandomAccessFile extends RandomAccessFile {
    public MyRandomAccessFile(String name, String mode) throws FileNotFoundException {
        super(name, mode);
    }
    public final short myReadShort() throws IOException {
        int ch1 = this.read();
        int ch2 = this.read();
        if ((ch1 | ch2) < 0) {
            throw new EOFException();
        }
        return (short) ((ch2 << 8) (ch1 << 0));
    }
    public final int myReadInt() throws IOException {
        int ch1 = this.read();
        int ch2 = this.read();
        int ch3 = this.read();
        int ch4 = this.read();
        if ((ch1 | ch2 | ch3 | ch4) < 0) {
            throw new EOFException();
        }
        return ((ch4 << 24) (ch3 << 16) (ch2 << 8) (ch1 << 0));
    }
}
就是把原来的代码拷贝出来,然后把移位的变量换一下,就能轻松搞定。

猜你喜欢

转载自bigdragon.iteye.com/blog/2360943