NIO概述
1.NIO是面向块(缓冲区)编程,旧IO是面向流编程。NIO是在JDK1.4后引入的
2.NIO 和 IO的区别:IO是面向流、阻塞IO、无选择器。 NIO是面向缓冲区、非阻塞IO、有选择器
3.Java中针对IO的一些核心的包和接口、类。
*java.nio 主要包含了各种与Buffer相关的类
* java.nio.channel 主要包含了与Channel和Selector相关的类和接口
* java.nio.charset 主要包含了与编码相关的类接口
* java.nio.channels.spi 主要包含了与Channel相关的服务提供者编程接口
* javan.nio.charset.spi 主要包含了与charset相关的服务提供者编程接口
4.目前需要掌握的核心就是三个包
* Buffer
* Channel
* CharSet
5.面向缓冲区编程
a.数据的读写必须经过缓冲区
b.我们可以使用Buffer所对应的子类来数据从通道(Channel)流向缓冲区
c.从缓冲区写到通道叫做读取缓冲区
Buffer缓冲区
Buffer是一个抽象类
子类有:
ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
核心类:
ByteBuffer和CharBuffer
ByteBuffer有一个子类 MappedByteBuffer
MappedByteBuffer类能够将文件直接映射到内存中,那么这样我们就可以像访问内存一样访问文件,非常方便
获取Buffer
获取ByteBuffer
static ByteBuffer allocate(int capacity)
分配一个新的字节缓冲区。
static ByteBuffer allocateDirect(int capacity)
分配新的直接字节缓冲区。
二者获取Buffer的区别
1.创建普通Buffer成本低,读写的效率不高
2.因为创建直接Buffer成本高,所以我们一般用在Buffer生存周期较长的时候使用
3.只有ByteBuffer才能够创建直接Buffer,其他的Buffer对象是不能够创建
4.如果创建了直接Buffer但是我又想要使用其他Buffer的功能,可以将ByteBuffer转换成其他Buffer
asIntBuffer()
-
四个非常重要的概念
capacity: 缓冲区的容量,不可以为负数,一旦创建了就不能够改变 limit: 无效缓冲区的第一个位置索引,limit后面的数据既不可读,也不可写 position : 下一个可以被读取或者写入的缓冲区位置索引 mark: 标记索引,该索引能够用于下次读取或者写入,它只能够在0-position之间
-
四个系数的关系:
0 < mark < postion < limit < capacity
-
五个方法
flip(): 将写模式切换为读模式, 将limit的值改为postion的值,同时将postion归0 特点: 就是为下一次数据的读取做好准备 clear(): 将读模式切换为写模式,将limit改为capacity的值,同时将postion归0 特点: 就是为下一次数据的写入做好准备 put(): 相对读取,向Buffer中存储数据 get(): 相对读取,从Buffer中获取数据 hasRemaining(): 判断当前位置和limit之间是否还有元素可处理
-
注意:
绝对读取: get(index) 不会影响position的位置 相对读取: put() get() 会影响,每次读取一次,指针后移
Channel通道
Channel 通道
-
Channel原理类似于传统的流对象,
FileInputStream FileOutputStream
-
但是有两个主要的区别
1.Channel能够将指定的部分或者全部文件映射到内存中 全部映射 MappedByteBuffer 部分文件映射 2.程序如果想要读取Channel中的数据,不能够直接读写,必须经过Buffer
-
Java中为Channel提供了如下常用的类
FileChannel 和文件相关的通道 DatagramChannel 和UDP协议传输数据相关的通道 SocketChannel 和TCP协议相关的数据传输通道 ServerSocket 和TCP协议相关的数据传输通道
获取FileChannel对象
-
和文件相关的普通流有哪些?
FileInputStream FileOutputStream RandomAccessFile
-
常用的方法
read() : 将Channel中的数据读取到Buffer中 write() : 向Buffer中写入数据 map(): 将channel中的数据全部或者部分映射到Buffer中 inChannel.map(mode, position, size) MappedByteBuffer mappBuffer = inChannel.map(MapMode.READ_ONLY, 0, srcFile.length());