【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

相关推荐
考虑考虑几秒前
Jpa使用union all
java·spring boot·后端
用户37215742613522 分钟前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊1 小时前
Java学习第22天 - 云原生与容器化
java
渣哥3 小时前
原来 Java 里线程安全集合有这么多种
java
间彧3 小时前
Spring Boot集成Spring Security完整指南
java
间彧4 小时前
Spring Secutiy基本原理及工作流程
java
Java水解5 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆7 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学7 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole7 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端