读写实践
  写操作主要是按照自己的数据类型,写入到直接内存中,注意每次写入数据的时候,position都会自动加上写入数据的长度,指向下一个该写入的起始位置:
  下面看看如何写入一段byte[]或者字符串:
  ByteBuffer buffer = ByteBuffer.allocateDirect(10);
  byte[] data = {1,2};
  buffer.put(data);
  System.out.println("写byte[]后 " + buffer);
  buffer.clear();
  buffer.put("hello".getBytes());
  System.out.println("写string后 " + buffer);
  输出的内容为:
  写byte[]后 java.nio.DirectByteBuffer[pos=2 lim=10 cap=10]
  写string后 java.nio.DirectByteBuffer[pos=5 lim=10 cap=10]
  读的时候,可以通过一个外部的byte[]数组进行读取。由于没有找到直接操作直接内存的方法: 因此如果想在JVM应用中使用直接内存,需要申请一段堆中的空间,存放数据。
  如果有更好的方法,还请留言。
  ByteBuffer buffer = ByteBuffer.allocateDirect(10);
  buffer.put(new byte[]{1,2,3,4});
  System.out.println("刚写完数据 " +buffer);
  buffer.flip();
  System.out.println("flip之后 " +buffer);
  byte[] target = new byte[buffer.limit()];
  buffer.get(target);//自动读取target.length个数据
  for(byte b : target){
  System.out.println(b);
  }
  System.out.println("读取完数组 " +buffer);
  输出为
  刚写完数据 java.nio.DirectByteBuffer[pos=4 lim=10 cap=10]
  flip之后 java.nio.DirectByteBuffer[pos=0 lim=4 cap=10]
  1
  2
  3
  4
  读取完数组 java.nio.DirectByteBuffer[pos=4 lim=4 cap=10]
  常用方法
  上面的读写例子中,有几个常用的方法:
  clear()
  这个方法用于清除mark和position,还有limit的位置:
  public final Buffer clear() {
  position = 0;
  limit = capacity;
  mark = -1;
  return this;
  }
  flip()
  这个方法主要用于改变当前的Position为limit,主要是用于读取操作。
  public final Buffer flip() {
  limit = position;
  position = 0;
  mark = -1;
  return this;
  }
  compact()
  这个方法在读取一部分数据的时候比较常用。
  它会把当前的Position移到0,然后position+1移到1。
  public ByteBuffer compact() {
  int pos = position();
  int lim = limit();
  assert (pos <= lim);
  int rem = (pos <= lim ? lim - pos : 0);
  unsafe.copyMemory(ix(pos), ix(0), rem << 0);
  position(rem);
  limit(capacity());
  discardMark();
  return this;
  }
  比如一段空间内容为:
  123456789
  当position的位置在2时,调用compact方法,会变成:
  345678989
  isDirect()
  这个方法用于判断是否是直接内存。如果是返回true,如果不是返回false。
  rewind()
  这个方法用于重置mark标记:
  public final Buffer rewind() {
  position = 0;
  mark = -1;
  return this;
  }