Buffer Writing and Reading

Buffers

Introducing Buffers

_buffer_存储固定数量的数据,它是我们和I/O服务打交道的媒介对象,主要供_channel_读写使用。

Buffer具有四个属性:

  • Capacity:该buffer能够存储的数据容量
  • Limit:buffer中可供读写的上边界
  • Position:位置指针,指示可以被读写的位置
  • Mark:位置标记,回头用

Buffer and its Children

Buffer方法:

Method Description
Object array() 如果该buffer背后是java数组,则返回该数组,否则抛异常
int arrayOffset() 如果该buffer背后是java数组,则返回当前buffer所基于数组的位置偏移量
int capacity() buffer
Buffer clear() 清空,position置0,limit置为capacity,放弃mark位置
Buffer flip() 翻转,limit 置为当前的position,position置0
boolean hasArray() 判断该buffer时候是语句java 数组的
boolean hasRemaining() 当前position和limit的间隔
boolean idDirect() 判断该buffer是否是直接字节缓冲,即不是基于java数组的
boolean isReadOnly 只读
int limit() limit位置
Buffer limit(int newLimit) 设置limit位置
Buffer mark() 标记位置
int position()
Buffer position(int newPositon) 设置新位置
int remaining() 空余容量
Buffer reset() 重置,将position指向之前的mark位置
Buffer rewind() 倒回,positon置0,放弃mark

Buffer都不是线程安全的,小心使用。

Buffers in Depth

尽管Buffer有多种,如ByteBufferCharBufferDoubleBuffer等,最基本的是ByteBuffer。我们主要围绕ByteBuffer来学习。

Buffer Creation

ByteBuffer的创建方式:

  • ByteBuffer allocate(int capacity):直接指定容量分配,基于数组的
  • ByteBuffer allocateDirect(int capacity):分配一个指定容量的直接字节缓冲,不是基于数组的
  • ByteBuffer wrap(byte[] array, int offset, int length):包裹一个数组进去
  • ByteBuffer wrap(byte[] array):一样

几个put()getI()方法。

Fliping Buffers

Marking Buffers

Buffer Subclass Operations

compact():将buffer中未写出的数据移到最头上

equals():只有buffer有相同元素类型,剩余元素相同,以及剩余元素内容相同才返回true

compareTo():比较剩余的元素序列,每个字节的比较

Byte Ordering大小端问题

Direct Byte Buffers

操作系统可以直接访问一个进程的地址空间,例如,操作系统可以直接访问JVM的进程地址空间,执行一个基于字节数组的数据传输操作。然而,JVM可能不是连续存储该字节数组的,或者说它的GC将该字节数组转移到了另一个位置。由于这些原因,就有了直接字节缓冲(direct byte buffer)。

直接字节缓冲直接与_channel_和本地代码交互,这是JVM操作I/O最有效的的方法。

当我们传递一个非直接字节缓冲,_channel_会创建一个直接字节缓冲,将非直接缓冲中的内容复制到直接字节缓冲区,然后在临时的直接字节缓冲区执行I/O操作,然后再将临时的直接字节缓冲区中的内容复制到非直接字节缓冲区,然后临时直接字节缓冲区会被GC收集掉。

直接字节缓冲区的创建是很昂贵的,因为JVM堆外面的内存需要系统来分配,初始化/清理这些内存会比在JVM内部要慢。

posted @ 2017-01-31 00:36  JintaoXIAO  阅读(191)  评论(0编辑  收藏  举报