当前位置:编程学习 > JAVA >>

java中的位运算

以下是一本书中的代码,不明白为什么要使用位运行和与运算,求解析,谢谢。
public class LengthFramer implements Framer {
  public static final int MAXMESSAGELENGTH = 65535;
  public static final int BYTEMASK = 0xff;
  public static final int SHORTMASK = 0xffff;
  public static final int BYTESHIFT = 8;

  private DataInputStream in; // wrapper for data I/O

  public LengthFramer(InputStream in) throws IOException {
    this.in = new DataInputStream(in);
  }

  public void frameMsg(byte[] message, OutputStream out) throws IOException {
    if (message.length > MAXMESSAGELENGTH) {
      throw new IOException("message too long");
    }
    // write length prefix
    out.write((message.length >> BYTESHIFT) & BYTEMASK);
    out.write(message.length & BYTEMASK);
    // write message
    out.write(message);
    out.flush();
  }

  public byte[] nextMsg() throws IOException {
    int length;
    try {
      length = in.readUnsignedShort(); // read 2 bytes
    } catch (EOFException e) { // no (or 1 byte) message
      return null;
    }
    // 0 <= length <= 65535
    byte[] msg = new byte[length];
    in.readFully(msg); // if exception, it's a framing error.
    return msg;
  }
} --------------------编程问答-------------------- 是要转化成16进制么~ --------------------编程问答-------------------- 由于String.length>=0,再加上限制条件:String.length<=65535(学过C的大都能一眼看出这个数是2^16-1)
等于是把字符串的长度限制成一个只有16位的无称号整数。

而红色的部分分别是取length的高8位与低8位。 --------------------编程问答--------------------   out.write((message.length >> BYTESHIFT) & BYTEMASK);
out.write(message.length & BYTEMASK);

右移八位要干啥???? --------------------编程问答--------------------
引用 2 楼 suwei2002 的回复:
而红色的部分分别是取length的高8位与低8位。

。。。有什么意义捏。。。。 --------------------编程问答--------------------
引用 2 楼 suwei2002 的回复:
由于String.length>=0,再加上限制条件:String.length<=65535(学过C的大都能一眼看出这个数是2^16-1)
等于是把字符串的长度限制成一个只有16位的无称号整数。

而红色的部分分别是取length的高8位与低8位。


这个是往流(套接字)中写入数据,为什么不直接写入呢? --------------------编程问答-------------------- out.write((message.length >> BYTESHIFT) & BYTEMASK);//先写高位俩字节
out.write(message.length & BYTEMASK);//再写低位俩字节
这样读取的时候先读俩字节×256+后俩字节=总长度了
java输出流写int的时候只写低位俩字节,所以out.write(65534)和out.write(254) 结果是一样的
即16进制的都是FE --------------------编程问答--------------------
引用 5 楼 kang273528 的回复:
引用 2 楼 suwei2002 的回复:
由于String.length>=0,再加上限制条件:String.length<=65535(学过C的大都能一眼看出这个数是2^16-1)
等于是把字符串的长度限制成一个只有16位的无称号整数。

而红色的部分分别是取length的高8位与低8位。


这个是往流(套接字)中写入数据,为什么不直接写入呢?

在下不熟悉Framer接口,本来是想来混个几分把Java板块也升到2级的。
但这里既然问到了,我就提点不成熟的看法吧。

这个类的功能粗略分析了一下,貌似是进行数据包的筛选的。它会把长度过长(65535为上限)的包抛掉。
至于红色部分的功能,这涉及到数据存储方式的问题。计算机内存存储数据有两种模式:大端模式(Big-Endian)和小端模式(Little-Endian),Big-Endian的内存地址分配是从大到小的(例如2001地址是在2000前面),而Little-Endian则与之相反(中国用得比较多的x86系列计算机都是Little-Endian的,所以接触到Big-Endian的可能较少)。
例如:一整数0x0d0f,存放地址为2000,
在B-Endian下,地址2000存放的数据是0d,而L-Endian下,地址2000存放的数据是0f。
用write打散成字节流后,B-Endian系统传输的顺序是0d->0f,L-Endian系统传输的则是0f->0d。
而在接收端,readUnsignedShort函数不知道发送方是B-Endian还是L-Endian,它统一按照B-Endian的方式处理(这个推论是从上面的代码分析出来的)。
因此,发送方要用位运算的方法来保证第一个传过去的字节是数据的高8位。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,