当前位置: 首页 > article >正文

【Java回顾】Day7 Java IO|分类(传输方式,数据操作)|零拷贝和NIO

# Java IO 知识体系

请添加图片描述

IO-分类(传输,操作)

传输方式

  • 字节流
    请添加图片描述

  • 字符流

  • 请添加图片描述

  • 字节流和字符流的区别

    • 字节流读取单个字节,字符流读取单个字符
    • 字节流来处理二进制文件(图片,MP3,视频文件),字符流(文本文件(特殊的二进制文件,使用某种编码,人可以阅读))
    • 字节流给计算机处理的,字符流给人看的。
  • 字节转字符Input/OutputStreamReader/Writer

    • 编码是将字节转字符,解码是将字符转字节

数据操作

  • 文件(file)
  • 数组([])
  • 管道操作
  • 基本数据类型
  • 缓冲操作
  • 打印
  • 对象序列化反序列化
  • 转换

请添加图片描述

零拷贝和NIO概述

NIO

  • 参考:https://javaguide.cn/java/io/io-model.html#nio-non-blocking-new-i-o

  • NIO是IO多路复用模型

    • 请添加图片描述

    • 线程首先发起调用,询问内核数据是否准备就绪。等准备就绪后,用户线程再发起read调用(数据从内核空间->用户空间)是阻塞的。

      • select调用,支持一次查询多个系统调用的可用状态,几乎所有的操作系统都支持。
      • epoll调用,linux 2.6内核,select调用的增强版本,优化IO执行效率
  • NIO中的多路复用器selector
    *

    • 请添加图片描述
  • 在高并发和高延迟的环境,适合用NIO提交效率。

  • 组成部分(3个)

    • Buffer缓冲区:读写。读:从Channel到buffer;写:从buffer到Channel。

    • Channel通道:双向可读可写的数据传输通道,实现数据的输入和输出。

    • Selector选择器:一个线程处理多个Channel,基于事件驱动的I/O多路复用模型。多个channel由selector来分配线程处理事件

    • 请添加图片描述

  • 详解

    • Buffer,BIO是缓冲流,NIO是缓冲区

      • 默认是写模式,flip()切换到读模式;clear()或compact()切换到写模式

      • 核心代码

        • 用静态方法创建,CharBuffer buffer = CharBuffer.allocate(8);
        • put写数据,buffer.put(‘a’).put(‘b’).put(‘c’);
        • get读数据,while (buffer.hasRemaining()) {
          System.out.print(buffer.get());
          }
        • 写→读,buffer.flip();
        • 读→写,buffer.clear();
      • import java.nio.*;
        
        public class CharBufferDemo {
            public static void main(String[] args) {
                // 分配一个容量为8的CharBuffer
                CharBuffer buffer = CharBuffer.allocate(8);
                System.out.println("初始状态:");
                printState(buffer);
        
                // 向buffer写入3个字符
                buffer.put('a').put('b').put('c');
                System.out.println("写入3个字符后的状态:");
                printState(buffer);
        
                // 调用flip()方法,准备读取buffer中的数据,将 position 置 0,limit 的置 3
                buffer.flip();
                System.out.println("调用flip()方法后的状态:");
                printState(buffer);
        
                // 读取字符
                while (buffer.hasRemaining()) {
                    System.out.print(buffer.get());
                }
        
                // 调用clear()方法,清空缓冲区,将 position 的值置为 0,将 limit 的值置为 capacity 的值
                buffer.clear();
                System.out.println("调用clear()方法后的状态:");
                printState(buffer);
        
            }
        
            // 打印buffer的capacity、limit、position、mark的位置
            private static void printState(CharBuffer buffer) {
                System.out.print("capacity: " + buffer.capacity());
                System.out.print(", limit: " + buffer.limit());
                System.out.print(", position: " + buffer.position());
                System.out.print(", mark 开始读取的字符: " + buffer.mark());
                System.out.println("\n");
            }
        }
        
      • 请添加图片描述

    • Channel 全双工

      • 常用通道

        • FileChannel 文件访问通道
        • SocketChannel,ServerSocketChannel TCP通信通道
        • DatagramChannl UDP通信通道
      • 核心方法

        • 读,读并写入到Buffer中
        • 写,将buffer数据写入channel中
      • RandomAccessFile reader = new RandomAccessFile("/Users/guide/Documents/test_read.in", "r"))
        FileChannel channel = reader.getChannel();//得到一个channel
        ByteBuffer buffer = ByteBuffer.allocate(1024);//字节缓冲区buffer
        channel.read(buffer);//读
        
    • Selector

      • 请添加图片描述

      • **epoll()**一个多路复用器Selector可以同时轮询多个Channel,由于JDK使用了epoll()代替select实现,因此没有最大连接句柄1024/2048的限制。可以连接成千上万的客户端

      • 监听事件类型

        • SelectionKey.OP_ACCPET 通道接受连接的事件,用于ServerSocketChannel
        • SelectionKey.OP_CONNECT 完成连接的事件,SocketChannel
        • SelectionKey.OP_READ 通道准备好进行读取的事件,有数据可读
        • SelectionKey.OP_WRITE,通道准备好写入的事件,写入数据

NIO零拷贝

  • 解决操作系统在处理I/O操作时频繁复制数据的问题

  • 零拷贝:执行IO操作时,CPU不需要将数据从一个存储区域复制到另一个存储区域,从而可以减少上下文切换以及CPU的拷贝时间

  • 请添加图片描述

  • 必备2次DMA(Direct memory access),依赖硬件完成,零拷贝是减少了CPU拷贝及上下文切换

  • Java对零拷贝的支持

    • MappedByteBuffer
    • FileChannel
    • S请添加图片描述

IO-分类(传输,操作)

传输方式

  • 字节流
    请添加图片描述

  • 字符流
    请添加图片描述

  • 字节流和字符流的区别

    • 字节流读取单个字节,字符流读取单个字符
    • 字节流来处理二进制文件(图片,MP3,视频文件),字符流(文本文件(特殊的二进制文件,使用某种编码,人可以阅读))
    • 字节流给计算机处理的,字符流给人看的。
  • 字节转字符Input/OutputStreamReader/Writer

    • 编码是将字节转字符,解码是将字符转字节

数据操作

  • 文件(file)
  • 数组([])
  • 管道操作
  • 基本数据类型
  • 缓冲操作
  • 打印
  • 对象序列化反序列化
  • 转换

请添加图片描述

零拷贝和NIO概述

NIO

  • 参考:https://javaguide.cn/java/io/io-model.html#nio-non-blocking-new-i-o

  • NIO是IO多路复用模型
    *

    • 请添加图片描述

    • 线程首先发起调用,询问内核数据是否准备就绪。等准备就绪后,用户线程再发起read调用(数据从内核空间->用户空间)是阻塞的。

      • select调用,支持一次查询多个系统调用的可用状态,几乎所有的操作系统都支持。
      • epoll调用,linux 2.6内核,select调用的增强版本,优化IO执行效率
  • NIO中的多路复用器selector
    *

    • 请添加图片描述
  • 在高并发和高延迟的环境,适合用NIO提交效率。

  • 组成部分(3个)

    • Buffer缓冲区:读写。读:从Channel到buffer;写:从buffer到Channel。
    • Channel通道:双向可读可写的数据传输通道,实现数据的输入和输出。
    • Selector选择器:一个线程处理多个Channel,基于事件驱动的I/O多路复用模型。多个channel由selector来分配线程处理事件
    • 请添加图片描述
  • 详解

    • Buffer,BIO是缓冲流,NIO是缓冲区

      • 默认是写模式,flip()切换到读模式;clear()或compact()切换到写模式

      • 核心代码

        • 用静态方法创建,CharBuffer buffer = CharBuffer.allocate(8);
        • put写数据,buffer.put(‘a’).put(‘b’).put(‘c’);
        • get读数据,while (buffer.hasRemaining()) {
          System.out.print(buffer.get());
          }
        • 写→读,buffer.flip();
        • 读→写,buffer.clear();
      • import java.nio.*;
        
        public class CharBufferDemo {
            public static void main(String[] args) {
                // 分配一个容量为8的CharBuffer
                CharBuffer buffer = CharBuffer.allocate(8);
                System.out.println("初始状态:");
                printState(buffer);
        
                // 向buffer写入3个字符
                buffer.put('a').put('b').put('c');
                System.out.println("写入3个字符后的状态:");
                printState(buffer);
        
                // 调用flip()方法,准备读取buffer中的数据,将 position 置 0,limit 的置 3
                buffer.flip();
                System.out.println("调用flip()方法后的状态:");
                printState(buffer);
        
                // 读取字符
                while (buffer.hasRemaining()) {
                    System.out.print(buffer.get());
                }
        
                // 调用clear()方法,清空缓冲区,将 position 的值置为 0,将 limit 的值置为 capacity 的值
                buffer.clear();
                System.out.println("调用clear()方法后的状态:");
                printState(buffer);
        
            }
        
            // 打印buffer的capacity、limit、position、mark的位置
            private static void printState(CharBuffer buffer) {
                System.out.print("capacity: " + buffer.capacity());
                System.out.print(", limit: " + buffer.limit());
                System.out.print(", position: " + buffer.position());
                System.out.print(", mark 开始读取的字符: " + buffer.mark());
                System.out.println("\n");
            }
        }
        
      • 请添加图片描述

    • Channel 全双工

      • 常用通道

        • FileChannel 文件访问通道
        • SocketChannel,ServerSocketChannel TCP通信通道
        • DatagramChannl UDP通信通道
      • 核心方法

        • 读,读并写入到Buffer中
        • 写,将buffer数据写入channel中
      • RandomAccessFile reader = new RandomAccessFile("/Users/guide/Documents/test_read.in", "r"))
        FileChannel channel = reader.getChannel();//得到一个channel
        ByteBuffer buffer = ByteBuffer.allocate(1024);//字节缓冲区buffer
        channel.read(buffer);//读
        
    • Selector

      请添加图片描述

      • **epoll()**一个多路复用器Selector可以同时轮询多个Channel,由于JDK使用了epoll()代替select实现,因此没有最大连接句柄1024/2048的限制。可以连接成千上万的客户端
      • 监听事件类型
        • SelectionKey.OP_ACCPET 通道接受连接的事件,用于ServerSocketChannel
        • SelectionKey.OP_CONNECT 完成连接的事件,SocketChannel
        • SelectionKey.OP_READ 通道准备好进行读取的事件,有数据可读
        • SelectionKey.OP_WRITE,通道准备好写入的事件,写入数据

NIO零拷贝

  • 解决操作系统在处理I/O操作时频繁复制数据的问题

  • 零拷贝:执行IO操作时,CPU不需要将数据从一个存储区域复制到另一个存储区域,从而可以减少上下文切换以及CPU的拷贝时间

  • 请添加图片描述

  • 必备2次DMA(Direct memory access),依赖硬件完成,零拷贝是减少了CPU拷贝及上下文切换

  • Java对零拷贝的支持

    • MappedByteBuffer

    • FileChannel

    • 请添加图片描述


http://www.kler.cn/a/510925.html

相关文章:

  • GraphRAG: Auto Prompt Tuning 实践
  • Java开发提速秘籍:巧用Apache Commons Lang工具库
  • 【部署】将项目部署到云服务器
  • 力扣hot100之螺旋矩阵
  • ESP8266-01S、手机、STM32连接
  • Java 8 Optional类
  • Linux 创建用户
  • 数据结构——链表和单向链表
  • 02内存结构篇(D2_剖析运行数据区)
  • Java——Stream流的peek方法详解
  • 【opencv】第9章 直方图与匹配
  • 基于.Net Core+Vue的文件加密系统
  • MySQL 可视化工具
  • 31、【OS】【Nuttx】OSTest分析(1):stdio测试(一)
  • MySQL程序之:使用类似URI的字符串或键值对连接到服务器
  • ubuntu24.0安装JDK8-281版本
  • 【游戏设计原理】71 - 兴趣曲线
  • AIGC视频生成明星——Emu Video模型
  • 【AI | pytorch】torch.view_as_complex的使用
  • 线性代数概述
  • 基于 Spring Cloud 、Spring Boot、 OAuth2 的 RBAC 企业快速开发平台
  • JAVA:MyBatis 缓存机制详解的技术指南
  • 云计算与物联网技术的融合应用(在工业、农业、家居、医疗、环境、城市等整理较全)
  • 通俗易懂:深入String 字符串常量池的存储机制
  • MQ架构测试
  • 【Rust自学】13.1. 闭包 Pt.1:什么是闭包、如何使用闭包