Java NIO概述

简介: IO与NIO的区别 IO是面向流的,而NIO是面向块(缓冲区)的。面向块的方式中,一次性可以获取或者写入一整块数据,而不需要一个字节一个字节的从流中读取。面向块的方式处理数据的速度会比流方式更快。 NIO基础 通道 Channel与缓冲器Buffer Buffer是一个保存数据的地方,包括刚刚写入的数据,以及被读取的数据,主要用来追踪系统的读写进程。

IO与NIO的区别

IO是面向流的,而NIO是面向块(缓冲区)的。面向块的方式中,一次性可以获取或者写入一整块数据,而不需要一个字节一个字节的从流中读取。面向块的方式处理数据的速度会比流方式更快。

NIO基础

通道 Channel与缓冲器Buffer

Buffer是一个保存数据的地方,包括刚刚写入的数据,以及被读取的数据,主要用来追踪系统的读写进程。

Channel与流模式比较类似,但是,永远无法将数据直接写入到Channel或者从Channel中读取数据。需要通过Buffer与Channel交互。

NIO的读与写

读取

第一步,获取通道

FileInputStream inputStream = new FileInputStream("read.txt");
FileChannel inputChannel = inputStream.getChannel();

第二步,创建缓冲器

ByteBuffer buffer = ByteBuffer.allocate(1024);

第三步,将channel中的数据读取到buffer中。相当于写入buffer

int readBytes = inputChannel.read(buffer);

写入

将数据写入到buffer中,然后再将buffer中的数据写入到channel中

FileOutputStream outputStream = new FileOutputStream("output.txt");
FileChannel outputChannel = inputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(new String("message").getBytes());
buffer.filp();
outputChannel.write(buffer);

Buffer细节

Buffer
通过 position, limit, capacity 可以控制读取和写入的数据。

以下均为伪代码:

put方法

bytes[postion++] = c;

flip方法:

limit = position;
position = 0;

get方法:

byte c = bytes[position++];

clear方法:

position = 0;
limit = capacity;

选择器 Selector

Selector 就是您注册对各种 I/O 事件的兴趣的地方,而且当那些事件发生时,就是这个对象告诉您所发生的事件。

以下我们看一下服务端如何将channel感兴趣的事件绑定在selector上。

        // 获得一个ServerSocket通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        // 设置通道为非阻塞
        serverChannel.configureBlocking(false);
        // 将该通道对应的ServerSocket绑定到port端口
        serverChannel.socket().bind(new InetSocketAddress(port));
        // 获得一个通道管理器
        Selector selector = Selector.open();
        //将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,注册该事件后,
        //当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

内部循环:
现在我们已经将感兴趣的IO事件注册到selector上,下面将进入主循环:

int num = selector.select();

Set selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();

while (it.hasNext()) {
     SelectionKey key = (SelectionKey)it.next();
     // ... deal with I/O event ...
}

这样,当时select返回时,channel中已经可以read或者write了。

总结

选择器selector 将 通道channel感兴趣的IO事件注册监听,当其返回时,channel即可对这些IO事件进行处理,一般将这些读写操作都会放到单独的线程中执行,提高吞吐率。

参考文献:
IBM Java NIO入门

目录
相关文章
|
16天前
|
IDE Oracle Java
java基础教程(1)-Java概述和相关名词解释
【4月更文挑战第1天】Java是1995年Sun Microsystems发布的高级编程语言,以其跨平台特性著名。它介于编译型和解释型语言之间,通过JVM实现“一次编写,到处运行”。Java有SE、EE和ME三个版本,分别针对标准、企业及嵌入式应用。JVM是Java虚拟机,确保代码在不同平台无需重编译。JRE是运行环境,而JDK包含开发工具。要安装Java开发环境,可从Oracle官网下载JDK,设置JAVA_HOME环境变量并添加到PATH。
|
1月前
|
存储 Java 数据处理
|
1月前
|
Java API
java中IO与NIO有什么不同
java中IO与NIO有什么不同
|
7天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
1月前
|
Java
JAVA异常概述
JAVA异常概述
8 1
|
1月前
|
存储 安全 Java
JAVA集合类概述
JAVA集合类概述
9 0
|
1月前
|
Oracle 安全 Java
Java语言概述
Java语言概述
10 0
|
1月前
|
Java 程序员 数据安全/隐私保护
二、Java性能概述
二、Java性能概述
33 3
|
2月前
|
移动开发 编解码 网络协议
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
|
2月前
|
网络协议 Java Linux
用Java来实现BIO和NIO模型的HTTP服务器(二) NIO的实现
用Java来实现BIO和NIO模型的HTTP服务器(二) NIO的实现