一、JAVA NIO概念
JAVA NIO是从JDK1.4就开始有的,之前只用过IO流,其实NIO和IO一样都是可以用来读取或者写入文件,只不过原来的IO是面向流进行操作的,而NIO是面向缓冲区进行操作
二、通过一个小例子初步了解下NIO如何进行文件读写
package com.boke.nio.base; import java.io.File; import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * 原IO和NIO分别实现读取、写入文件 * @author lenovo * */ public class MyFirstNio { public static void main(String[] args) throws Exception { File file = new File("C:/Users/lenovo/Desktop/test.txt"); readio(file);//原IO readnio(file);//NIO } //原IO进行文件读操作 public static void readio(File file) throws Exception{ FileInputStream fis = new FileInputStream(file); byte[] arr = new byte[1024]; int len = -1; System.out.println("原IO:"); while((len = fis.read(arr))!=-1){ System.out.println(new String(arr,0,len,"utf-8")); } if(fis!=null){ fis.close(); } } //NIO方式进行文件读操作 public static void readnio(File file) throws Exception{ FileInputStream fis = new FileInputStream(file); FileChannel channel = fis.getChannel();//通过流获取唯一通道 ByteBuffer buffer = ByteBuffer.allocate(1024);//创建一个缓冲区 System.out.println("NIO:"); while (true) { // clear方法重设缓冲区,使它可以接受读入的数据 buffer.clear(); // 从输入通道中将数据读到缓冲区 int r = channel.read(buffer); // read方法返回读取的字节数,可能为零,如果该通道已到达流的末尾,则返回-1 if (r == -1) { break; } byte[] array = buffer.array(); System.out.println(new String(array,0,r,"utf-8")); } if(fis!=null){ fis.close(); } } }
通过上面的例子,可以很明显的看出IO和NIO一个最大的区别,IO是直接将数据读取至流中,而NIO数据终将在缓冲区中
三、根据例子对NIO关键概念进行讲解
(1)例子中的FileChannel
通道,可以理解为它就是原IO中的流,但是读取的数据不是放在流中,而必须通过channel.read(buffer)将数据读取到缓冲区buffer中,如果取数据的话也是先将数据放至缓冲区中。
通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类), 而通道可以用于读、写或者同时用于读写。因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在UNIX模型中,底层操作系统通道是双向的。
(2)例子中的ByteBuffer
说明一下,ByteBuffer并不是NIO中唯一的缓冲区类型,是使用最多的一种缓冲区类型,当然还有其他缓冲区对象,只是类型不同而已,包括:
ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer
缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。每一个缓冲区都有复杂的内部统计机制,接下来我会开始了解一下。
标记下:上面如果看完不是很明白的话可以看看 http://zhangshixi.iteye.com/blog/679959作者的系列文章即可