JAVA中NIO的技术原理及SpringBoot代码实例详解

 更新时间:2025年10月09日 10:03:12   作者:低音钢琴  
Java NIO(Non-blocking I/O)是Java1.4引入的非阻塞I/O API,通过Channel、Buffer和Selector实现高效、低延迟的异步文件传输,适用于高并发服务器端场景,本文给大家介绍JAVA中NIO的技术原理及SpringBoot代码实例,感兴趣的朋友一起看看吧

介绍NIO:概念与技术原理

Java NIO(Non-blocking I/O)是Java 1.4版本引入的一组I/O(输入输出)API,旨在提供比传统的Java I/O(如InputStreamOutputStream)更高效的I/O操作,特别是在高并发、低延迟的场景中。NIO的核心思想是提供非阻塞、事件驱动的I/O方式,尤其适用于服务器端需要高效处理多个客户端连接的场景。

1. NIO的核心概念

NIO的核心概念包括:

  • Channel:代表一个可以进行I/O操作的连接,类似于传统I/O中的流(Stream)。Channel提供了读取和写入数据的方法。常见的Channel有FileChannelSocketChannelServerSocketChannel等。
  • Buffer:所有的I/O操作(读写)都依赖于缓冲区(Buffer)。Buffer是一个容器,提供对数据的存储和访问。
  • Selector:Selector使得一个线程可以监听多个Channel上的事件,支持非阻塞模式下的事件处理。通过Selector可以轮询多个Channel,处理I/O事件。

2. 技术原理

NIO的非阻塞技术基于以下几个关键要素:

  • 非阻塞模式:传统I/O中,线程每次读取或写入数据时,都会被阻塞,直到操作完成。而NIO允许线程在进行I/O操作时不被阻塞,线程可以同时处理多个I/O任务,提升系统并发性。
  • 事件驱动:通过Selector,NIO允许服务器在一个线程中处理多个客户端的I/O操作,极大减少了线程的数量,并避免了线程的上下文切换开销。
  • 异步操作:NIO支持异步I/O,可以在执行I/O操作时将任务交给操作系统或其他线程处理,当操作完成后再进行后续处理。这对于处理大规模的文件上传和下载特别有效。

NIO 实现文件异步上传和下载

架构图

为了更直观地理解文件上传和下载的流程,下面是该系统的架构图:

以下是实现文件异步上传和下载的基本代码。该示例采用Java NIO的SocketChannelServerSocketChannel实现客户端与服务端的异步文件传输。

服务端代码(Server)

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
public class NioFileServer {
    private static final int PORT = 8080;
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(PORT));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("Server is listening on port " + PORT);
        while (true) {
            if (selector.select() > 0) {
                for (SelectionKey key : selector.selectedKeys()) {
                    if (key.isAcceptable()) {
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int bytesRead = socketChannel.read(buffer);
                        if (bytesRead == -1) {
                            socketChannel.close();
                        } else {
                            buffer.flip();
                            Files.write(Paths.get("received_file.txt"), buffer.array(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
                        }
                    }
                }
                selector.selectedKeys().clear();
            }
        }
    }
}

客户端代码(Client)

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
public class NioFileClient {
    private static final String SERVER_HOST = "localhost";
    private static final int SERVER_PORT = 8080;
    public static void main(String[] args) throws IOException {
        Path filePath = Paths.get("file_to_send.txt");
        FileChannel fileChannel = FileChannel.open(filePath, StandardOpenOption.READ);
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress(SERVER_HOST, SERVER_PORT));
        socketChannel.configureBlocking(false);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while (fileChannel.read(buffer) != -1) {
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
        }
        fileChannel.close();
        socketChannel.close();
    }
}

###代码说明

  • 服务端
    • 创建一个ServerSocketChannel并绑定到指定端口。
    • 使用Selector监听连接请求和数据读事件。
    • 在非阻塞模式下接受客户端连接,并读取传输的数据,将文件内容写入磁盘。
  • 客户端
    • 打开文件并通过SocketChannel发送文件内容。
    • 在非阻塞模式下,将文件分块写入到服务器。

写在最后

Java NIO通过非阻塞I/O操作与事件驱动机制,使得多线程和高并发处理变得更加高效。通过使用NIO的ChannelBufferSelector,我们可以实现如文件异步上传与下载等高效的文件处理操作。上述代码展示了一个简单的客户端-服务器文件传输实例,能够实现文件的异步上传和下载,并能够处理大规模并发请求,适合在高并发环境下使用。

到此这篇关于JAVA中NIO的原理及SpringBoot代码实例的文章就介绍到这了,更多相关java nio原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot中集成各种日志框架Logback、Log4j2和Java Util Logging的步骤和示例代码

    Spring Boot中集成各种日志框架Logback、Log4j2和Java Util 

    这篇文章主要介绍了Spring Boot中集成各种日志框架Logback、Log4j2和Java Util Logging,通过实例代码介绍了集成Logback、Log4j2和Java Util Logging的基本步骤,你可以根据自己的需求进行配置和扩展,以满足更复杂的日志需求,需要的朋友可以参考下
    2023-11-11
  • SpringMVC接收与响应json数据的几种方式

    SpringMVC接收与响应json数据的几种方式

    这篇文章主要给大家介绍了关于SpringMVC接收与响应json数据的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者使用springmvc具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Spring学习笔记2之表单数据验证、文件上传实例代码

    Spring学习笔记2之表单数据验证、文件上传实例代码

    这篇文章主要介绍了Spring学习笔记2之表单数据验证、文件上传 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • 教你用Java在个人电脑上实现微信扫码支付

    教你用Java在个人电脑上实现微信扫码支付

    今天给大家带来的是Java实战的相关知识,文章围绕着Java在个人电脑上实现微信扫码支付展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 基于JVM-jinfo的使用方式

    基于JVM-jinfo的使用方式

    这篇文章主要介绍了JVM-jinfo的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • java迭代子模式详解

    java迭代子模式详解

    这篇文章主要为大家详细介绍了java迭代子模式的相关资料,需要的朋友可以参考下
    2016-02-02
  • JAVA SFTP文件上传、下载及批量下载实例

    JAVA SFTP文件上传、下载及批量下载实例

    本篇文章主要介绍了JAVA SFTP文件上传、下载及批量下载实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • IDEA mybatis Mapper.xml报红的最新解决办法

    IDEA mybatis Mapper.xml报红的最新解决办法

    这篇文章主要介绍了IDEA mybatis Mapper.xml报红的解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • SpringBoot发送异步邮件流程与实现详解

    SpringBoot发送异步邮件流程与实现详解

    这篇文章主要介绍了SpringBoot发送异步邮件流程与实现详解,Servlet阶段邮件发送非常的复杂,如果现代化的Java开发是那个样子该有多糟糕,现在SpringBoot中集成好了邮件发送的东西,而且操作十分简单容易上手,需要的朋友可以参考下
    2024-01-01
  • BigDecimal的toString()、toPlainString()和toEngineeringString()区别及用法详解

    BigDecimal的toString()、toPlainString()和toEngineeringString()区

    使用BigDecimal进行打印的时候,经常会对BigDecimal提供的三个toString方法感到好奇,以下整理3个toString方法的区别及用法,需要的朋友可以参考下
    2023-08-08

最新评论