JAVA NIO
系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,传统的IO系统具有一些问题,read()将一直等待在端口一边读取字节内容,为了提高IO的效率,JAVA增加了另一套IO系统,Java NIO非堵塞应用通常适用用在I/O读写等方面。NIO支持面向缓存基于通道的I/O操作,JDK7中,增加了对文件处理和文件特性的支持。
NIO系统构建与两个基础之上,缓存和通道。缓存用于容纳数据,通道表示打开的到I/O设备的链接。NIO的操作需要首先获取连接I/O设备的通道以及用于容纳数据的缓存,然后操作缓存,根据需要输入输出数据。
缓存
缓存定义在java.nio包中,所有缓存都是Buffer类的子类,Buffer类定义了缓存的核心功能,当前位置,界限和容量。主要方法:get(),put(),从缓存存取数据,reset(),将缓存的当前位置重置为之前设置的标记,rewind(),将调用缓存的位置设置为0通道
通道定义在java.nio.channels包中,实现了Channel接口并扩展了Closeable和AutoCloseable接口,可以使用带资源的try语句进行管理。获取通道有两种方式,
一种是对支持通道的对象调用getChannel()方法,支持的I/O类包括:DatagramSocket,FileInputStream,FileOutputStream,RandomAccessFile,ServerSocket,Socket。根据调用对象的类型返回特定类型的通道,FileInputStream,FileOutputStream,RandomAccessFile返回FileChannel类型,Socket返回SocketChannel类型。
另一种是使用Files类定义的静态方法getByteChannel()获取字节通道,该方法返回SeekableByteChannel对象。
Files类
文件的操作由文件的Path对象指定,Path是一个封装文件路径的接口,描述了目录结构中文件的位置。Files类支持打开创建复制移动指定路径文件的静态方法,还可以获取Path对象的文件属性信息。示例代码:同通道读取文件到缓存
int count;
try(SeekableByteChannel fChan = Files.newByteChannel(Paths.get("d:/usb.txt"))){
ByteBuffer mBuf = ByteBuffer.allocate(128);
do{
count = fChan.read(mBuf);
if(count != -1){
mBuf.rewind();
for(int i = 0; i < count; i ++)
System.out.print((char)mBuf.get());
mBuf.rewind();
}
}while(count != -1);
}catch(IOException e){
e.printStackTrace();
}
读取文件的另一种方式是将文件映射到缓存,优点是缓存自动包含文件的内容,无须显示读操作。通过在通道上调用map()方法可以将文件的数据映射到缓存,map()方法定义在FileChannel,所以需要把通道转换为FileChannel类型。
try(FileChannel fChan = (FileChannel)Files.newByteChannel(Paths.get("d:/usb.txt"))){
long size = fChan.size();
MappedByteBuffer mBuf = fChan.map(FileChannel.MapMode.READ_ONLY,0,size);
for(int i =0 ; i < size; i ++)
System.out.print((char)mBuf.get());
}catch(IOException e){
e.printStackTrace();
}