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

对IO流原理及、分类及IO模型的一个大概认识【Java基础题】

1.流的分类

  • 根据操作数据单位分类:

    • 字节流
    • 字符流

        一般来说,字符流会比字节流效率更高,因为1个字符一般比1个字节(8bit)大(it depends on 具体的编码规则,例如UTF-8中1个中文等于3个字节,1个英文等于1个字节)。可以理解为一个工人一次可以搬的东西更多,则效率更高。但是,它们的应用场景不同,使用字节流来操作二进制的文件(例如图片、视频等)可以保证对文件的无损操作。而字符流就天然地更适合文本文件

  • 根据数据流的流向分类:

    • 输入流
    • 输出流

        输入、输出是以JAVA程序(运行时内存)的角度来定义的,从外部数据源(硬盘或网络传输等外部数据源)传输到JAVA程序是输入,从JAVA程序传输到外部是输出。

        字节流根据输入输出又分为字节输入流,字节输出流。

        字节输入流的抽象基类是InputStream、字节输出流的抽象基类是OutputStream

        字符流根据输入输出又分为字符输入流,字符输出流。

        字符输入流的抽象基类是Reader、字符输出流的抽象基类是Writer

        这些抽象基类是不能被直接实例化的,只能用相应的子类来实例化对象。

(1)JAVA中IO流总共涉及40多个类,但是都是由:InputStream、Outputstream、Reader、Writer这四个抽象基类派生的

(2)由上述四种类派生出来的子类名称都是以其父类名作为其名称后缀。

JAVA IO体系图参考:Java的IO流体系-CSDN博客

  • 根据流的角色分类:

    • 节点流 Node Stream
    • 处理流/包装流 

节点流是可以从特定的数据源读写数据。是比较底层的流,因为它门是直接连接、操作数据源的,没有过多的处理和包装。包装流(处理流);对节点流进行包装,使它功能更加强大,既可以消除不同节点流的实现差异,也可以提供更方便的方法完成输入输出。

例如:BufferedReader继承Reader,它有一个Reader类型的成员变量in,这个in可以是Reader的任何子类,也就是BufferedReader是对这个节点流进行了一个封装。这里的设计模式属于修饰器模式。

处理流的功能主要主要体现在以下两个方面:

1.性能的提高:主要是以增加缓存的方式来提高输入输出的效率。

缓冲流的工作原理是预先从数据源读取数据存入内部缓冲区,或将输出数据暂存到内部缓冲区,直到缓冲区满了再一次性写入目的地。这样减少了与物理读写设备的交互次数,因为访问磁盘或网络资源通常比访问内存慢得多。缓冲流自动管理缓冲区,开发者不需要关心缓冲区的具体操作细节。

Java提供了四个主要的缓冲流类,分别用于不同的输入输出流:

  1. BufferedInputStreamBufferedOutputStream:用于增加缓冲功能的字节流。它们分别包装任何类型的InputStreamOutputStream,提供了缓冲的读写能力。

  2. BufferedReaderBufferedWriter:用于增加缓冲功能的字符流。它们分别包装任何类型的ReaderWriter,同样提供了缓冲的读写能力。

2.操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。

其他节点流

  • 对象流ObjectInputStreamObjectOutputStream 能够将基本数据类型和对象进行序列化(以指定的格式写入文件,非文本,dat后缀)和反序列化(读取到程序内存中),传入对象流中的对象一定要实现序列化Serializable接口,否则就会报NotSerializableException。要注意的是write和read的顺序要一一对应。序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员。
  • 标准输入输出
    • System.in 标准输入  它的编译类型是 InputStream 它的运行类型是BufferedInputStream 默认设备是键盘
    • System.out 标准输出 它的编译类型是 PrintStream 运行时类型是 PrintStream  默认设备是屏幕
  • 转换流:InputStreamReader、OutputStreamWriter---->用于将字节流转换成字符流,可用于解决中文乱码问题
  • 打印流:打印流只有输出流没有输入流,PrintStream、PrintWriter

2.文件与流之间的关系

流是文件(数据)的通道

创建流对象和指定的文件关联起来后,就用这个流对象操作文件

相关的类:

1.FileInputStream 构造方法是需要与实际的文件或者File对象相关联起来(也就是一个FileInputStream对应一个文件?)

在Java中,FileInputStream是用于从文件中读取数据的一种输入流。当你创建一个FileInputStream实例时,你必须指定一个文件源,这可以是一个文件路径的字符串,也可以是一个File对象。如果指定的文件不存在,构造FileInputStream时会抛出一个FileNotFoundException,这意味着在创建流对象之前,必须确保文件确实存在且对当前程序可读。

每个FileInputStream流对象和一个具体的文件是一对一对应的。这意味着流对象是专门为了从一个特定的文件中读取数据而打开的,它与那个文件绑定在一起。如果你需要从另一个文件读取数据,就必须创建一个新的FileInputStream对象来指向新的文件。

这种设计反映了流(Stream)的概念:流是一次性的、有方向的数据序列,它们连接程序和数据源或数据目标。在文件IO中,数据源或目标就是特定的文件。一旦流与数据源或目标建立了连接,它就只能用于那个特定的数据源或目标。如果要处理另一个文件,就需要开启一个新的流。

这不仅适用于FileInputStream,还适用于Java中的其他类型的流,如FileOutputStream(用于写文件)、ObjectInputStreamObjectOutputStream(用于读写对象)等。每次使用这些流时,都需要为它们指定一个具体的数据源或目标

举个例子,如果你先后需要从两个不同的文件中读取数据,你需要为每个文件创建各自的FileInputStream对象

2.FileOutputStream  

3.FileReader 继承的是--->InputStreamReader--->Reader

4.FileWriter 继承的是--->OutputStreamWriter--->Writer

FileWriter调用write方法,要close或者flush才能写到指定的文件?为什么?

Write只是写到FileWriter对象,最后close才会保存到磁盘。FileWriter的底层是用的FileOutputStream,最终要写到磁盘用的是FileOutputStream的Write

其他具体的细节内容需要在后面的文章中拓展。 

3.什么是IO模型?BIO NIO AIO?

IO模型:IO模型决定了数据如何在应用程序和网络间传输。IO模型是系统底层的支持,不同语言和框架对这些模型的支持和实现方式可能会有所不同。虽然IO模型最初是针对网络IO操作来描述的,但它们的基本原则和方法同样适用于本地IO操作。

BIO:BlockingIO,传统IO模型,同步阻塞IO--->可以大概对应的实现是java中java.io包

应用程序执行IO操作时,如果数据未准备好,它将一直等待数据准备完毕。一旦数据准备好了,再将数据从内核空间拷贝到用户空间,此过程中应用程序是阻塞的。

每个请求都需要在处理过程中阻塞等待。(比如socket在服务端一般是while(ture){server.accept()},没有接收到数据的时候,这个线程就会一直停在这里)

这意味着如果要同时处理多个请求,就需要为每个请求分配一个线程,随着请求数量的增加,线程数量也会相应增长,这在并发量较高时会占用大量的系统资源。

NIO:Non-BlockingIO,同步非阻塞IO--->可以大概对应的实现是java中java.nio包

应用程序执行IO操作时,如果数据未准备好,它不会等待数据准备完毕,而是直接返回一个错误码。应用程序可以继续做其他事情,但需要不断地检查数据是否准备好。

可以让你进行非阻塞的IO操作。核心组成部分包括Buffers(缓冲区)Channels(通道)Selectors(选择器)等。NIO允许单个线程管理多个IO操作。如果在非阻塞模式下没有IO操作可用,线程可以进行其他任务,而不是阻塞等待,从而提高了资源利用率。Java中的java.nio包提供了NIO功能,核心类包括ByteBufferCharBufferSelectorServerSocketChannelSocketChannel等。

AIO:  AsynchronousIO,异步非阻塞IO--->可以大概对应的实现是java中java.nio.channels中的异步类

应用程序发起IO操作后可以直接进行其他任务,当IO操作完成后,系统会通知应用程序IO操作已经完成。

AIO适用于连接数较多且连接时间较长的应用,Java中的java.nio.channels.AsynchronousFileChanneljava.nio.channels.AsynchronousSocketChannel是AIO模型的两个例子。


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

相关文章:

  • 真·香!深度体验 zCloud 数据库云管平台 -- DBA日常管理篇
  • WPF+MVVM案例实战(二十一)- 制作一个侧边弹窗栏(AB类)
  • 虚拟化环境中的精简版 Android 操作系统 Microdroid
  • Java面向对象 C语言字符串常量
  • Linux 之 信号概念、进程、进程间通信、线程、线程同步
  • ClkLog企业版(CDP)预售开启,更有鸿蒙SDK前来助力
  • 算法第三十天-矩阵中移动的最大次数
  • Android 性能优化——APP启动优化
  • 供应链投毒预警 | 开源供应链投毒202402月报发布啦
  • UnityShader(十七)透明效果
  • 基于支持向量机(svm)的人脸识别
  • Flutter-仿淘宝京东录音识别图标效果
  • 【Vue3】自定义Input组件
  • HTML5语义化元素
  • 以太坊开发学习-solidity(三)函数类型
  • 项目性能优化—使用JMeter压测SpringBoot项目
  • 【Unity】详细介绍
  • 【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架构、Master节点 Node节点 K8S架构图
  • lv17 BOA服务器搭建 4
  • YOLOv8改进 | 图像去雾 | MB-TaylorFormer改善YOLOv8高分辨率和图像去雾检测(ICCV,全网独家首发)
  • 字节-安全研究实习生--一面
  • 愚人节礼物(C++)
  • 第二十五章 Web Gateway 管理页面概述 - 可用选项
  • 详解IP安全:IPSec协议簇 | AH协议 | ESP协议 | IKE协议
  • 容器部署对比:通用容器部署 vs 使用腾讯云容器镜像服务(TCR)部署 Stable Diffusion
  • 十、MySQL主从架构配置