JAVA New IO入门(NIO系列三)

昨天的文章,大家了解了JAVA BIO的阻塞编程方式对性能有较大的影响,JDK1.4加入了新的IO特性(NIO),比较重要的是新增了高性能Buffer和非阻塞多路复用网络编程模式。

今天带大家首先对NIO有个初步的认知,带着目标读完本文:

  1. 知道了Channel和Buffer是怎么相互配合的。

  2. 大概了解Buffer的状态、属性、方法。(后续会重点说明代码上的应用)

1. 传统JAVA IO

这里总结下IO,还需要注意继承图,下面给出:

JAVA New IO入门(NIO系列三)

Input

JAVA New IO入门(NIO系列三)

Output

  • IO重点是流的概念,Stream从一个数据源中获取,不管获得Input还是Output,都是单向的。

  • IO实现的是装饰者设计模式,按照功能的不同,可以把Stream包装成Buffered功能的、具有Data数据类型的IO。

  • 数据类型的转换以及Buffered的支持,都需要通过包装的形式实现,性能较低。

2. JAVA New IO

  • 不再区分Input和Output,抽象成了Channel,是双向的,可面向文件或者Socket编程。

  • 缓冲区和Data数据类型的转换,抽象成Buffer,例如ByteBuffer以及导出的View Buffers。

JAVA New IO入门(NIO系列三)

Channel借助Buffer的读写操作

2.1 Channel

  • Channel的获取,主要有3个,从文件流中获取、从Socket中获取、从Pipe中获取,如下图代码

JAVA New IO入门(NIO系列三)

从流中获取

JAVA New IO入门(NIO系列三)

从Pipe中获取

JAVA New IO入门(NIO系列三)

一般都是从Channel中获取socket

2.2 Buffers

channel负责运输通道,起到履带的作用,但是没有容器承载数据也是白搭。所有需要Buffer这个容器承载数据。Buffer有7种类型,实际上是JAVA的8种基础数据类型除去boolean类型,有:ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,Longuffer,ShortBuffer。

Buffer的属性

JAVA New IO入门(NIO系列三)

  • capacity :缓冲区能够容纳的数据元素的最大数量。

  • limit :缓冲区的第一个不能被读或写的元素,缓冲创建时,limit 的值等于 capacity 的值。

  • position :下一个要被读或写的元素的索引。缓冲创建时,position的值等于0。

    所以有公式:0 <= position <= limit <= capacity

Buffer的操作

Buffer有读写两种操作,读操作有channel.read(buffer)和buffer.put(127),而写操作有channel.write(buffer)和buffer.get()。

上面的这段话很重要,务必理解清楚了。可以结合最上面的channel、buffer关系图理解

  • clear() :让Buffer为新一轮的读取操作做准备,设置limit的值=capacity,position=0.(为channel.read()和buffer.put()操作做准备工作)

  • flip() :为写操作做准备,设置limit = position,然后设置position = 0。(channel-write 或 buffer.get 操作)

  • rewind() :在读写模式下都可用,它单纯的将当前位置置0。一般用于复制上一次读取的数据。

Buffer的创建

要想获得一个Buffer对象首先要进行分配。 每一个Buffer类都有一个allocate方法。例如下面是一个分配1024字节的的ByteBuffer的例子。

ByteBuffer buf = ByteBuffer.allocate(1024);

分配一个可存储1024个字符的CharBuffer:

CharBuffer buf = CharBuffer.allocate(1024);

如下API

JAVA New IO入门(NIO系列三)

Buffer的API接口

API注意:

  • allocate的capacity表示多个T。

  • asReadOnlyBuffer、duplicate、slice操作保持buffer内容不变化,但是内部属性会变化:

    • asReadOnlyBuffer返回只读buffer,mark、position、limit不同,改变buffer会影响此readOnly返回的Buffer

    • duplicate返回新的buffer和原有buffer内容相同,但mark、position、limit不同,改变buffer值会相互影响。

    • slice方法返回buffer剩余的内容,修改buffer相互影响。

  • 带有index的get和put操作不影响position的位置,不带index的是相对操作,影响postion。

读完后,是否完成阅读目标,希望我写的能多少帮的到你,不足望指正。

后续会用代码让你全面理解Channel和Buffer的编程思维。


分享到:


相關文章: