Java笔记(18)NIO流
Java笔记(18)NIO
1.NIO流
NIO是JDK1.4后出的一个新的流体系,它的实现原理与原来的IO流有很大的不同,可以通过将文件区域映射到内存中的方式来实现传输,因此它的效率要比IO流快很多。IO流与NIO的区别在于:IO是面向流的,而NIO是面向缓冲区的,并且在读写过程中IO流是阻塞式,而NIO可以通过选择器选择通道,是非阻塞式的。
Java NIO由以下几个核心部分组成
- Channels(通道)
- Buffers(缓冲区)
- Selectors(选择器)
Channels和Buffers (通道与缓冲区)
标准IO流通过字节流和字符流进行操作,而NIO通过通道和缓冲区对数据进行操作,在NIO中,数据总是从通道读入缓冲区中,或从缓冲区中写入通道。并且在NIO中,线程是非阻塞的,即在通道读取数据的时候,你还可以让线程去干其他的事情,不必像IO流中要一直等到数据读写完毕;
Channel是一个对象,可以通过它读取和写入数据。可以把它看做IO中的流。但是它和流相比还有一些不同:
- Channel是双向的,既可以读又可以写,而流是单向的
- Channel可以进行异步的读写
- 对Channel的读写必须通过buffer对象
在Java NIO中Channel主要有如下几种类型:
FileChannel:从文件读取数据的
DatagramChannel:读写UDP网络协议数据
SocketChannel:读写TCP网络协议数据
ServerSocketChannel:可以监听TCP连接
其他的Channel类和Buffer可以通过API查看,具体的就不再列出;
Selector(选择器)
Selector允许单线程处理多个Channels,用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。
NIO实例:
1.读数据到缓冲区
//1.获取Channel通道对象,需要通过一个流对象获取
FileInputStream fin = new FileInputStream( "test.txt" );
FileChannel fc = fin.getChannel();
//2.创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
//3.从通道读取数据到缓冲区
fc.read(buffer);
-------------------------------------------------------------------------
2.读写结合,复制文件
public static void copyFileNIO(String src,String dest) throws IOException{
//声明源文件和目标文件
FileInputStream fis=new FileInputStream(new File(src));
FileOutputStream fos=new FileOutputStream(new File(dest));
//获得传输通道channel
FileChannel inChannel=fis.getChannel();
FileChannel outChannel=fos.getChannel();
//获得容器buffer
ByteBuffer buffer=ByteBuffer.allocate(1024);
while(true){
//判断是否读完文件,读到最后一个字节read方法会返回-1
int eof =inChannel.read(buffer);
if(eof==-1){
break;
}
//反转缓冲区,即将缓冲区当前位置重设为0
buffer.flip();
//开始写
outChannel.write(buffer);
//写完要清除缓冲区,使得下一次写入的数据重新从缓冲区最开始写入
buffer.clear();
}
inChannel.close();
outChannel.close();
fis.close();
fos.close();
}
//除此外NIO中还可以通过transferTo方法直接将一个通道的字节写到另一个通道,具体可查看API自行体验
此外更多NIO类可以通过API学习掌握,由于目前学习开发中很少使用NIO类,大多都是传统的IO流方式实现读写传输,所以就不再一一列举介绍。
在JDK7还出现了NIO的一些方便进行文件操作的类,如Path,Paths,Files类等,大家可以通过网络和API查看具体使用和原理。