Java NIO 笔记

Java Nio相关的包

  • java.nio:包含各种与Buffer相关的类
  • java.nio.channels:包含各种与Channel和Selector相关的类
  • Java.nio.charset:包含与字符集相关的类
  • java.nio.channels.spi:包含于Channel相关的服务提供者编程接口
  • java.nio.charset.spi:包含与字符集相关的服务提供者编程接口

Channel与Buffer详解

Channel与Buffer是nio中的两个核心对象

Channel简介

Channel是对传统的输入/输出系统的模拟,在新IO系统中所有的数据都需要通过通道传输。
Channel与传统的InputStream、OutputStream最大的区别在于它提供了一个map()方法,
通过该map()方法可以直接将“一块数据”映射到内存中。
Channel是双向的通道,而传统的输入流和输出流是单向的。
如果说传统的输入输出系统是面向流的处理,则新的IO则是面向块的处理。

Buffer简介

Buffer可以被理解成一个容器,它的本质是一个数组,发送到Channel中的所有对象都必须首先放到Buffer中,而Channel中读取的数据也必须先放到Buffer中。

除了Channel和Buffer之外,新IO还提供了用于Unicode字符串映射成字节序列以及逆映射操作的Charset类,还提供了用于支持费阻塞是输入输出的Selector类.

使用Buffer

从内部结构上来看,Buffer就像一个数组,可以保存多个类型相同的数据。Buffer是一个抽象类,其最常用的子类是ByteBuffer,它可以在底层字节数组上进行get/set操作。

除了ByteBuffer之外,对应于其他基本数据类型(boolean)都有相应的Buffer类: CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer

上面这些Buffer类,除了ByteBuffer之外,他们都采用相同或相似的方法来管理数据,只是各自管理的数据类型不同而已.
这些Buffer类都没有提供构造器,创建他们的实例的方法是:
* static XxxBuffer allocate(int capacity)创建一个容量为capacity的XxxBuffer对象

使用较多的是ByteBuffer和CharBuffer,其他Buffer子类较少用到.
其中ByteBuffer类还有一个子类:MapppedByteBuffer,用于表示Channel将磁盘文件的部分或全部内容映射到内存中后得到的结果,通常MappedByteBuffer对象由Channel的map()方法返回。

在Buffer中有三个重要概念:capicity,limit,position和两个方法:flip()和clear()

  • capacity:缓冲区容量,该值不能为负数,缓冲区创建后不可修改
  • limit:界限,表示limit后的区域不可读也不可写,position不能往limit后的方向移动
  • position:指明下一个可以被读或写的缓冲区位置索引
  • flip():将limit设置为position所在位置,并将position设置为0,为输出Buffer中已经有的数据做好准备
  • clear():将limit设置为capacity,将position设置为0,为再次往Buffer中输入数据做好准备
    此外Buffer还支持mark,允许position直接定位到mark处。mark的值只能在0和position之间。

Buffer包含的常用的方法

  • int capacity(): 返回Buffer的capacity大小
  • boolean hasRemaining(): 判断position到limit之间是否还有元素供处理
  • int remainning():返回当前位置
  • int limit():返回Buffer的界限的位置
  • Buffer limit(int nweLt):重新设置界限(limit)的值,并返回一个新的limit的缓冲区对象
  • Buffer mark():设置Buffer的mark位置,它只能在0和position之间做mark
  • int position:返回position的值
  • int position(int newPs):设置Buffer的position,并返回position被修改后的Buffer对象
  • Buffer reset():将位置(position)转到mark所在位置
  • Buffer rewind():将位置(position )设置成0,取消设置的mark
  • put():放入数据
  • get():取出数据

使用Channel

Channel类似于传统的流对象,但与传统的流对象有两个主要区别

  • Channel可以直接将指定文件的部分或全部直接映射成Buffer
  • 程序不能直接访问Channel中的数据,包括读取,写入都不行,Channel只能与Buffer交互。如果要从Channel中取得数据,必须先用Buffer从Channel中取出一些数据,然后让程序从Buffer中取出这些数据;如果要将程序中的数据写入Channel,先把数据放入Buffer中,程序再将Buffer里的数据写入Channel中。

Channel的实现类:

  • DatagramChannel:支持UDP网络通信的Channel
  • FileChannel:支持文件读写的Channel
  • Pipe.SinkChannel:支持线程之间通信的Channel
  • Pipe.SourceChannel:支持线程之间通信的Channel
  • SelectableChannel:支持线程之间通信的Channel
  • ServerSocketChannel :Socket通信的服务端
  • SocketChannel:Socket通信的客户端
posted @ 2017-08-27 21:17  渐入佳境coder  阅读(194)  评论(0编辑  收藏  举报