NIO basics

NIO是在JDK1.4引入的,代表New IO,具有以下特性:

  • 为所有的原始类型提供缓冲(Buffer)支持
  • 使用Java.nio.charset.Charset作为字符集编解码解决方案
  • 增加通道(Channel)对象,作为新的原始I/O抽象
  • 支持锁和内存映射文件的文件访问接口
  • 提供了基于Selector的异步网络IO

与流式的IO不同,NIO是基于块(Block)的,它以块为基本单位处理数据。在NIO中,最为重要的两个组件是缓冲Buffer和通道Channel。缓冲是一块连续的内存块,是NIO读写数据的中转地。通道表示缓冲数据的源头或目的地,它用于向缓冲读取或者写入数据,是访问缓冲的接口。

下面用一个简单的实例来看一下NIO的基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class FileCopy {
public static void main(String[] args) {
try {
FileCopy.nioCopyFile("test.txt", "testcp.txt");
} catch (IOException e) {
e.printStackTrace(); }
}
public static void nioCopyFile(String resource, String destination) throws IOException {
FileInputStream fis = new FileInputStream(resource);
FileOutputStream fos = new FileOutputStream(destination);
FileChannel readChannel = fis.getChannel();
FileChannel writeChannel = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true){
buffer.clear();
int len = readChannel.read(buffer);
if ( len == -1 )
break;
buffer.flip();
writeChannel.write(buffer);
}
readChannel.close();
writeChannel.close();
}
}

实例中需要理解的几个点:

  • 本例实现了文件拷贝功能
  • 本例中使用了文件通道FileChannel,是Channel的一种
  • FileChannel中的read和write方法通过操作Buffer达到读写文件的目的
  • Buffer的常用方法
    • allocate:创建Buffer
    • clear:position置0,mark清空,limit设置为capacity,为重新写入Buffer做准备
    • flip:position置0,mark清空,limit设置为position,在读写切换时调用

Buffer是NIO中非常重要的一个类,我们会在后续的文章里说明它的基本原理和常用操作。

注:本文大部分内容摘自《Java程序性能优化》(清华大学出版社 葛一鸣 等编著)