在NIO中有几个比较关键的概念:Channel,Buffer,Selector。
1. Channel(通道)
顾名思义,就是通向什么的道路,为某个提供了渠道。
在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:
package com.mycom.test.nio; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class TestIO { public static void main(String[] args) { try { File file = new File("d:/data.txt"); InputStream inputStream = new FileInputStream(file); byte[] bytes = new byte[1024]; inputStream.read(bytes); inputStream.close(); System.out.println(new String(bytes)); } catch (IOException e) { e.printStackTrace(); } } }这里的InputStream实际上就是为读取文件提供一个的通道。
但是,在传统IO中,Stream是单向的,比如InputStream只能进行读取操作,OutputStream只能进行写操作。而NIO中Channel是双向的,既可用来进行读操作,又可用来进行写操作。
以下是常用的几种通道:
- FileChannel:可以从文件读或者向文件写入数据;
- SocketChanel:以TCP来向网络连接的两端读写数据;
- ServerSocketChannel:能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的Socket Channel来进行数据读写;
- DatagramChannel:以UDP协议来向网络连接的两端读写数据。
下面给出通过FileChannel来向文件中写入数据的一个例子:
package com.mycom.test.nio; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * FileChannel读取文件 * * @author guweiqiang */ public class TestFileChannel { public static void main(String[] args) { try { File file = new File("d:/writeData.txt"); FileOutputStream outputStream = new FileOutputStream(file); FileChannel fileChannel = outputStream.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); String ss = "hello world!"; buffer.put(ss.getBytes()); buffer.flip(); //此处必须要调用buffer的flip方法 fileChannel.write(buffer); fileChannel.close(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
通过上面的程序会向工程目录下的data.txt文件写入字符串"java nio",注意在调用channel的write方法之前必须调用buffer的flip方法,否则无法正确写入内容(flip方法的作用是首先读取数据到Buffer,然后反转Buffer,接着再从Buffer中读取数据)。