首页 > 编程语言 >熟练掌握并使用Java的NIO操作

熟练掌握并使用Java的NIO操作

时间:2024-11-01 19:42:06浏览次数:3  
标签:Java NIO 熟练掌握 buffer ByteBuffer java socketChannel

Java的New Input/Output (NIO)库是一种非阻塞I/O操作的集合,旨在提高I/O操作的效率。相比于传统的Java I/O(基于java.io包),NIO提供了更灵活、更强大的I/O处理能力。以下是一篇详细的文章,帮助你彻底熟练掌握并使用Java的NIO操作。

一、Java NIO概述
Java NIO(New I/O)主要包含以下几个核心组件:

Channels(通道):用于数据的读写操作,是NIO的核心组件之一。常见的通道类型有:
FileChannel:用于文件读写。
SocketChannel:用于网络客户端的读写。
ServerSocketChannel:用于网络服务器的读写。
DatagramChannel:用于无连接的UDP通信。
Pipe.SourceChannel 和 Pipe.SinkChannel:用于线程间的管道通信。
Buffers(缓冲区):用于临时存储数据。缓冲区是一个字节容器,并提供了一组方法来操作这些字节。常见的缓冲区类型有:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
Selectors(选择器):用于管理多个Channel,并可以检测哪些Channel可以进行读、写、连接等I/O操作。
二、Buffers(缓冲区)详解

  1. 缓冲区的创建
    java
    ByteBuffer buffer = ByteBuffer.allocate(1024); // 分配一个容量为1024字节的缓冲区
  2. 缓冲区的操作
    写数据:
    java
    buffer.put((byte) 10);
    buffer.put(new byte[]{1, 2, 3, 4});
    buffer.put(new byte[5], 1, 3); // 从索引1开始,复制3个字节
    切换读写模式:
    在写数据之后,需要切换到读模式:

java
buffer.flip();
读数据:
java
while (buffer.hasRemaining()) {
byte b = buffer.get();
System.out.println(b);
}
重置缓冲区:
java
buffer.clear(); // 准备再次写数据
标记和重置:
java
buffer.mark();
buffer.position(5);
buffer.reset(); // 重置到标记的位置
三、Channels(通道)详解

  1. FileChannel
    java
    RandomAccessFile file = new RandomAccessFile("example.txt", "rw");
    FileChannel fileChannel = file.getChannel();

// 写数据到文件
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Hello NIO".getBytes());
buffer.flip();
fileChannel.write(buffer);

// 读数据从文件
buffer.clear();
fileChannel.read(buffer);
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
http://yim6.5hai.com/
fileChannel.close();
file.close();
2. SocketChannel 和 ServerSocketChannel
客户端:

java
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 8080));

ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Hello Server".getBytes());
buffer.flip();
socketChannel.write(buffer);

buffer.clear();
socketChannel.read(buffer);
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}

socketChannel.close();
服务器:

java
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);

while (true) {
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel != null) {
socketChannel.configureBlocking(false);

    ByteBuffer buffer = ByteBuffer.allocate(1024);  
    socketChannel.read(buffer);  
    buffer.flip();  
    while (buffer.hasRemaining()) {  
        System.out.print((char) buffer.get());  
    }  

    buffer.clear();  
    buffer.put("Hello Client".getBytes());  
    buffer.flip();  
    socketChannel.write(buffer);  
    socketChannel.close();  
}  

}
四、Selectors(选择器)详解
选择器允许一个单独的线程管理多个通道(Channel),并且能够知道哪些通道可以进行I/O操作。
http://yim7.5hai.com/
java
Selector selector = Selector.open();

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
selector.select(); // 阻塞直到至少有一个通道准备好

Set<SelectionKey> selectedKeys = selector.selectedKeys();  
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();  

while (keyIterator.hasNext()) {  
    SelectionKey key = keyIterator.next();  

    if (key.isAcceptable()) {  
        ServerSocketChannel server = (ServerSocketChannel) key.channel();  
        SocketChannel client = server.accept();  
        client.configureBlocking(false);  
        client.register(selector, SelectionKey.OP_READ);  
    } else if (key.isReadable()) {  
        SocketChannel client = (SocketChannel) key.channel();  
        ByteBuffer buffer = ByteBuffer.allocate(1024);  
        client.read(buffer);  
        buffer.flip();  
        while (buffer.hasRemaining()) {  
            System.out.print((char) buffer.get());  
        }  
        client.close();  
    }  

    keyIterator.remove();  
}  

}
五、总结
Java NIO提供了一种高效、灵活的方式来处理I/O操作。通过理解并使用Buffers、Channels和Selectors,可以编写出高并发、高性能的网络应用程序。掌握NIO的关键在于理解其非阻塞的特性和事件驱动的设计模式。希望这篇文章能帮助你彻底掌握Java的NIO操作。

标签:Java,NIO,熟练掌握,buffer,ByteBuffer,java,socketChannel
From: https://www.cnblogs.com/yimai/p/18521140

相关文章

  • 基于java+SpringBoot+Vue的“衣依”服装销售平台设计与实现
    项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot+mybatis+Maven+mysql5.7或8.0等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个......
  • 基于java+SpringBoot+Vue的IT技术交流和分享平台设计与实现
    项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot+mybatis+Maven+mysql5.7或8.0等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个......
  • javascript 基本语法,变量,运算符【知识点整理】
    JavaScript(ES5)JavaScript的基本语法和变量变量声明与变量赋值的方法:vara=5;vara=5;varb=4;vara=3,b=2;vara,b,c=5;vara=b=c=1;变量的命名规范首字符:英文和下划线组成:英文数字下划线禁忌:关键字、保留字##Unicode在HTML中,Unicode字符......
  • Java 中如何处理日期和时间?_1
    在Java中处理日期和时间可以通过几种核心技术实现,这些技术包括:`java.util.Date`类,`java.util.Calendar`类、`java.text.DateFormat`类,以及Java8引入的新日期和时间API——`java.time`包的类。其中,Java8的新API提供了更为简洁、易读和强大的日期时间处理能力,推荐优先使用。`jav......
  • 排序算法:从原理到 Java 实现
    文章目录排序算法:从原理到Java实现一、引言二、常见排序算法原理及Java实现(一)冒泡排序(BubbleSort)(二)选择排序(SelectionSort)(三)插入排序(InsertionSort)(四)快速排序(QuickSort)(五)归并排序(MergeSort)(六)堆排序(HeapSort)三、性能比较与分析(一)时间复杂度(二)空间复杂度(三)稳定......
  • 基于springboot的Java学习论坛平台
    基于springboot的Java学习论坛平台摘要在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括学习平台的网络应用,在外国学习平台已经是很普遍的方式,不过国内的管理平台可能还处于起步阶段。学习平台具有学习信息管理功能的选择。学习平台采用java技术......
  • Java方法设计原则与实践:从Effective Java到团队案例
    作者:京东物流京东物流背景本文通过阅读《EffectiveJava》、《CleanCode》、《京东JAVA代码规范》等代码质量书籍,结合团队日常代码实践案例进行整理,抛砖引玉、分享一些在编写高质量代码方面的见解和经验。这些书籍提供了丰富的理论知识,而团队的实际案例则展示了这些原则在实际......
  • 【Java】ThreadLocal详解
    引言在多线程编程中,如何安全地共享数据是一个重要的课题。Java提供了ThreadLocal类,以便在每个线程中维护线程局部变量,允许每个线程拥有自己的独立变量副本。本文将探讨ThreadLocal的工作原理、使用场景以及一些最佳实践。1.什么是ThreadLocal?ThreadLocal是Java......
  • 二:java 基础知识(2)-- 初始java/语法基础
    目录idea中文插件第一个Java程序Java数据类型,常量与变量1.数据类型    1.1基本数据类型    1.2引用数据类型2.常量2.1特性2.2 定义常量​编辑3.变量        3.1 变量的定义与初始化        3.2变量的类型局部变量:在......
  • Java 在金融科技(FinTech)中的应用
    在探讨Java在金融科技(FinTech)中的应用时,首先要明白Java由于其高性能、安全性、可移植性等特性,在金融行业中占据了举足轻重的地位。这些特点使得Java成为开发高频交易系统、风险管理平台、数据处理框架等金融应用的首选语言。尤其是在安全性方面,Java提供了一套严格的安全机制,包......