一、NIO的概念
Java NIO(New IO)是一个在JDK1.4中推出的新IO API。它以更接近操作系统底层的方式进行文件操作,相对于传统的IO流,在性能和灵活性方面都有很大的提升。Java NIO主要由以下几个核心部分构成:
- Channels: 通道
- Buffers: 缓冲区
- Selectors: 选择器
通道和缓冲区是NIO数据的核心,选择器则是一个可以用来监视多个通道的对象,是否有事件(如新连接、数据接收)发生。这种方式比旧的阻塞式I/O处理方式更为高效。
二、Channel
Channel,通道是NIO中的一个基本概念。它指的是可以进行IO操作的对象,如文件或网络连接。Channel与传统IO中的流(Stream)有一些重要的区别:
- 可以既读又写(流必须分别进行读写)
- 可以异步地进行读写
- 从Channel中读取的数据总是被读到Buffer中,从Buffer写入到Channel中的数据也总是被写入到Channel中
下面的代码段说明了如何创建一个文件通道并读取其中的内容:
try { RandomAccessFile aFile = new RandomAccessFile("file.txt", "rw"); FileChannel inChannel = aFile.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buffer); while (bytesRead != -1) { System.out.println("Read " + bytesRead); buffer.flip(); while(buffer.hasRemaining()){ System.out.print((char) buffer.get()); } buffer.clear(); bytesRead = inChannel.read(buffer); } aFile.close(); } catch (IOException e) { e.printStackTrace(); }
三、Buffer
Buffer是一个用于存储数据的内存块。在NIO库中,所有数据都是用缓冲区处理的。缓冲区实质上是一个数组,并提供了一组方法,方便对数据的存储和检索。
下面的代码段说明了如何创建一个缓冲区并使用put()方法将数据写入缓冲区,并使用flip()方法将Buffer从写模式切换到读模式:
ByteBuffer buf = ByteBuffer.allocate(48); buf.put("hello world".getBytes()); buf.flip(); while(buf.hasRemaining()){ System.out.print((char) buf.get()); }
四、Selector
Selector是SelectableChannel对象的多路复用器,用于检查一个或多个通道是否处于准备好状态(如读就绪、写就绪)。
下面的代码段说明了如何使用Selector的代码:
Selector selector = Selector.open(); channel.configureBlocking(false); SelectionKey key = channel.register(selector, SelectionKey.OP_READ); while(true) { int readyChannels = selector.select(); if(readyChannels == 0) continue; SetselectedKeys = selector.selectedKeys(); Iterator keyIterator = selectedKeys.iterator(); while(keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if(key.isAcceptable()) { // a connection was accepted by a ServerSocketChannel. } else if (key.isConnectable()) { // a connection was established with a remote server. } else if (key.isReadable()) { // a channel is ready for reading } else if (key.isWritable()) { // a channel is ready for writing } keyIterator.remove(); } }
五、总结
通过对NIO三个核心部分(通道、缓冲区、选择器)的介绍和示例代码的讲解,可以明确NIO相对于传统IO在性能和灵活性方面的提升。对于Java开发人员,掌握NIO的基础知识,并深入理解其使用方式,将大幅提升开发效率和性能。