如何分析NIO

一、NIO概述

NIO(Non-blocking I/O,非阻塞I/O)是Java中的一个高性能I/O框架,它提供了一种简单、高效的I/O处理方式,NIO的核心思想是将I/O操作从同步变为异步,从而提高程序的并发性能,NIO主要包括Buffer、Channel和Selector三个核心组件,通过这三个组件可以实现非阻塞的文件读写、网络通信等功能。

如何分析NIO

二、NIO的基本概念

1. Buffer

Buffer是NIO中用于存储数据的容器,它可以在内存中直接进行读写操作,提高了I/O操作的效率,NIO中的Buffer分为两类:ByteBuffer和CharBuffer,ByteBuffer主要用于处理字节数据,而CharBuffer主要用于处理字符数据。

2. Channel

Channel是NIO中用于处理I/O操作的通道,每个Channel对应一个文件或网络连接,通过Channel可以进行数据的读取、写入等操作,NIO中的Channel分为两类:FileChannel和SocketChannel,FileChannel用于处理文件I/O操作,而SocketChannel用于处理网络I/O操作。

3. Selector

Selector是NIO中的选择器,它负责管理多个Channel的状态,当某个Channel上有事件发生时(如读、写事件),Selector会通知关联的线程进行处理,这样可以实现多个线程同时处理多个Channel的I/O操作,提高程序的并发性能。

三、NIO的工作流程

1. 创建FileChannel或SocketChannel对象,并与指定的文件或网络连接建立关联关系。

2. 创建一个Selector对象,并将需要处理的Channel注册到Selector上。

3. 向Selector注册感兴趣的事件类型(如读、写事件)。

4. 调用Selector的select方法,等待事件发生,当事件发生时,Selector会通知关联的线程进行处理。

5. 在处理事件的线程中,通过Selector获取关联的Channel,并进行相应的I/O操作。

6. 关闭Selector和相关资源。

四、NIO的示例代码

下面是一个简单的NIO示例代码,实现了一个简单的文件复制功能:

```java

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

如何分析NIO

import java.util.Iterator;

import java.util.Set;

public class NioDemo {

public static void main(String[] args) throws IOException {

// 创建文件输入输出流

FileInputStream fis = new FileInputStream("source.txt");

FileOutputStream fos = new FileOutputStream("destination.txt");

// 创建文件通道

FileChannel inChannel = fis.getChannel();

FileChannel outChannel = fos.getChannel();

// 创建选择器

Selector selector = Selector.open();

// 向选择器注册读事件

inChannel.register(selector, SelectionKey.OP_READ);

// 创建服务器套接字通道,并绑定端口监听连接请求

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.bind(new InetSocketAddress(8080));

// 向选择器注册服务就绪事件,并将服务器套接字通道注册到选择器上

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

// 进入事件循环,等待事件发生并处理

while (true) {

int readyChannels = selector.select(); // 等待事件发生,超时时间为0表示立即返回,不等待;其他正数表示等待的时间(单位:毫秒)

if (readyChannels == 0) { // 如果超时时间到了,继续等待下一个事件循环;否则跳出循环,处理已发生的事件

如何分析NIO

continue;

} else { // 处理已发生的事件

Set selectedKeys = selector.selectedKeys(); // 获取已选中的键集合(包括关注的事件类型和对应的通道)

Iterator keyIterator = selectedKeys.iterator(); // 遍历键集合(注意要使用迭代器而不是普通for循环)

while (keyIterator.hasNext()) { // 遍历已选中的键集合(即已发生的事件)

SelectionKey key = keyIterator.next(); // 获取当前键(即当前已发生的事件)

if (key != null) { // 如果当前键不为空(即存在已发生的事件)

if (key.isAcceptable()) { // 如果当前键是服务就绪事件(即有新的客户端连接请求)

ServerSocketChannel server = (ServerSocketChannel) key.channel(); // 获取服务端通道(即新建立的客户端连接)

SocketChannel client = serverSocketChannel.accept(); // 接受客户端连接请求,返回一个新的客户端通道(即与客户端建立连接的套接字)

client.configureBlocking(false); // 将客户端通道设置为非阻塞模式(因为NIO是基于事件驱动的,不需要使用同步I/O)

client.register(selector, SelectionKey.OP_READ); // 向选择器注册读事件(即准备接收客户端发送的数据)

client.write(ByteBuffer.wrap("Hello, World!".getBytes())); // 向客户端发送数据(这里只是简单地发送了一行文本)

} else if (key.isReadable()) { // 如果当前键是读事件(即有数据可读)

// 根据当前的SelectionKey获取关联的通道(即读事件的源通道)和服务端的套接字通道(即客户端连接的源套接字)

SocketChannel client = (SocketChannel) key.channel(); // 获取客户端通道(即与客户端建立连接的套接字)和服务器套接字通道(即服务端监听客户端连接请求的套接字)

ByteBuffer buffer = ByteBuffer.allocate(1024); // 根据需要分配缓冲区大小(这里为1KB)的空间来存储数据(这里只是简单地读取了一行文本)

int bytesRead = client.read(buffer); // 从客户端通道中读取数据到缓冲区中(这里只是简单地读取了一行文本)

if (bytesRead > 0) { // 如果读取到了数据(即缓冲区中有数据)则准备将其写入到目标通道中(这里只是简单地将数据写入到了文件通道中)

buffer.flip(); // 切换缓冲区为读模式(即将写模式切换为读模式,以便写入数据到目标通道中)

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/28226.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2023-11-19 01:21
Next 2023-11-19 01:22

相关推荐

  • java如何判断目录是否存在文件

    Java如何判断目录是否存在在Java中,我们可以使用java.io.File类的exists()方法和isDirectory()方法来判断一个目录是否存在,下面是一个简单的示例:import java.io.File;public class CheckDirectoryExists { public static void mai……

    2024-01-11
    0166
  • Java中BIO、NIO、AIO的示例分析

    在Java网络编程中,BIO、NIO和AIO是非常重要的概念,它们分别代表了Java网络编程的三种不同模式:阻塞I/O、非阻塞I/O和异步I/O,这三种模式各有优缺点,适用于不同的场景,本文将对这三种模式进行详细的介绍,并通过实例代码进行分析,最后对它们的性能进行比较。二、BIO(Blocking I/O)1. 原理BIO,即Bloc……

    2023-11-05
    0211
  • java怎么设置文件编码格式不变

    Java设置文件编码格式的方法在Java中,我们可以通过java.nio.charset.Charset类来设置文件的编码格式,Charset类是Java 7引入的一个用于表示字符集的抽象类,它提供了一些常量和工具方法,用于处理不同的字符集。1、1 使用Charset类的静态方法创建指定编码格式的Charset对象Java提供了一些预……

    2023-12-20
    0139
  • Java实现服务器临时文件生成 (java生成服务器临时文件)

    在Java中,我们可以通过java.nio.file.Files和java.nio.file.Path类来创建临时文件,这些类位于Java的NIO(New Input/Output)库中,该库提供了一种高效的方式来处理文件I/O操作。以下是一个简单的示例,演示如何在Java中生成一个临时文件:import java.io.IOExce……

    2024-03-15
    0148
  • Java NIO核心部分由哪些组成

    Java NIO(New Input/Output)是Java的一个用于处理输入输出的框架,它提供了与标准I/O不同的I/O工作方式,Java NIO核心部分主要由以下几个部分组成:1. Channels(通道):Channels是NIO中的核心组件之一,它类似于流,但不同的是,流是单向的,而Channels是双向的,Channels……

    2023-11-10
    0127
  • nio服务器

    Nimble服务器是一种快速、高效、稳定的解决方案,它为企业和个人提供了一种可靠的网络服务,Nimble服务器的主要特点是高性能、高可靠性和易于管理,在这篇文章中,我们将详细介绍Nimble服务器的技术特点、应用场景以及如何选择合适的Nimble服务器。Nimble服务器的技术特点1、高性能Nimble服务器采用了先进的硬件配置和优化……

    2024-02-27
    0108

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入