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的基本用法:

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程序性能优化》(清华大学出版社 葛一鸣 等编著)