【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

相关推荐
晓风残月( ̄ε(# ̄)~1 分钟前
Spring参数校验,数组入参校验 :List<E>
java·经验分享·spring boot·后端·spring·spring cloud·list
我想学LINUX3 分钟前
【2024年华为OD机试】(B卷,100分)- 数据分类 (Java & JS & Python&C/C++)
java·c语言·javascript·python·华为od
2501_901839524 分钟前
Ruby语言的软件开发工具
开发语言·后端·golang
孤魂23318 分钟前
获取文章列表功能
java·spring boot
wy02_22 分钟前
【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
java·单例模式·设计模式
蒙娜丽宁23 分钟前
【Python】深入探讨Python中的单例模式:元类与装饰器实现方式分析与代码示例
开发语言·python·单例模式
asaasaaax27 分钟前
【黑马python 第十章:数据可视化】99-104
开发语言·python·信息可视化
李歘歘31 分钟前
Golang——常用库context和runtime
开发语言·后端·golang
李歘歘35 分钟前
Golang——常用库sync
开发语言·爬虫·golang