NIO
一 概述
1.NIO
New IO,从java1.4版本引入的新IO,可以替代标准的IO。NIO操作一般流程:
2.Channel
代表一个与数据源的开放连接,可以读写数据,这种读写操作都是基于数据块。
3.Buffer
channel读写数据的缓冲区,channel将读取的数据存放到Buffer中,将Buffer中的数据写入文件中。
4.Selector
允许一个线程监控多个channel。
5.RandomAccessFile
一个同时支持读写、随机访问的文件操作对象,相当于一个包含文件全部字节的数组。
二 NIO与IO对比
1.基本数据单位
IO以字节或者字符为基本单位,NIO以数据块为基本单位。
2.阻塞
IO操作阻塞线程,NIO不会阻塞线程。
3.索引
IO操作的流不存在索引,无法指定操作位置。NIO的数据中存在索引,可以指定操作位置。
4.锁
IO不支持锁,NIO支持锁,锁的作用是控制对文件的访问。
三 Channel
1.对象创建:
基于输入或输出流创建对象:
InputStream is=new FileInputStream(String name); FileChannel channel=is.getChannel();
基于RandomAccessFile对象创建对象
RandonAccessFile file=new RandomAccessFile(String name ,"rw"); FileChannel channel=file.getChannel();
2.基于输入流创建的对象只能输入,基于输出流创建的对象只能输出,而基于RandomAccessFile创建的对象既可以输入也可以输出。
3.Channel中的数据存在索引,可以指定读写位置。
4.常用方法
- truncate(long size):从开头截取指定字节长度的内容,其余部分删除。如果长度大于文件当前大小,该操作失效。
四 Buffer
NIO为每一个基本数据类型都提供了一个缓冲区,操纵方法相同,下面以ByteBuffer为例进行梳理。
1.三个重要属性
- position:当前光标位置,用于确定读写的起点。
- limit:上限,用于确定读写的范围,不包含所在索引。
- capacity:容量,用于确定所能存放的最大数据量。
2.对象创建
ByteBuffer byteBuffer=ByteBuffer.allocate();//通过分配指定长度的存储单位来创建缓冲区 ByteBuffer byteBuffer=ByteBuffer.wrap(byte[] array);//基于数组创建缓冲区
3.常用方法:
- put(Object data):将数据写入当前位置,同时将光标向前移动一个数据单位。
- get():获取当前位置的数据,同时将光标向前移动一个数据单位。
- flip():通过调整position与limit的值切换读写模式,position=0,limit=position。
- clear():并非清空缓冲区,而是调整position=0,limit=capacity,mark=-1。
- array():将ByteBuffer中的数据复制的数组中。
五 MappedByteBuffer
在系统当中建立文件的映射,如果采用读写模式,那么对该映射的操作会反映到文件中。
由于将文件映射到内存中,资源消耗较大,只有在文件较小的情况下才将文件映射到内存中。
获取对象
MappedByteBuffer mbb=channel.map(MapMode mode,long offset,long size);
有3中映射方式:
- READ_ONLY:映射内容只允许读,不允许修改。
- READ_WRITE:映射内容既允许读,也允许改,修改内容会反映到文件中。
- PRIVATE:在本地创建一个副本,读写操作都是针对副本,写不会反映到原始文件中。
不能仅仅停滞在实现上,应该去追求代价更小、性能更优的实现