Java中的IO框架设计思想

写在前面

首先本篇是参照知乎某匿名用户的回答而写的,在征求TA的同意之后,我将他的回答与我的个人理解综合起来写成本篇博客,如果存在不清楚、不明白甚至是错误的内容,请评论指出或私信给我也行,我会及时改正的。


正文

        首先在理解Java的IO框架之前,我们先复习一下计算机的构成。

 冯·诺依曼计算机模型:

  1. 运算器:计算机中执行各种算术和逻辑运算操作的部件。运算器的基本操作包括加、减、乘、除四则运算,与、或、非、异或等逻辑操作,以及移位、比较和传送等操作,亦称算术逻辑部件(ALU)
  2. 控制器:由程序计数器、指令寄存器、指令译码器、时序产生器和操作控制器组成,它是发布命令的“决策机构”,即完成协调和指挥整个计算机系统的操作。运算器和控制器统称中央处理器,也叫做CPU。中央处理器是电脑的心脏
  3. 存储器:存储器分为内存和外存。内存是电脑的记忆部件,用于存放电脑运行中的原始数据、中间结果以及指示电脑工作的程序。外存就像笔记本一样,用来存放一些需要长期保存的程序或数据,断电后也不会丢失,容量比较大,但存取速度慢。当电脑要执行外存里的程序,处理外存中的数据时,需要先把外存里的数据读入内存,然后中央处理器才能进行处理。外存储器包括硬盘、光盘和优盘
  4. 输入设备:输入设备是向计算机输入数据和信息的设备。是计算机与用户或其他设备通信的桥梁。输入设备是用户和计算机系统之间进行信息交换的主要装置之一。键盘,鼠标,摄像头,扫描仪,光笔等都属于输入设备
  5. 输出设备:是计算机硬件系统的终端设备,用于接收计算机数据的输出显示、打印、声音、控制外围设备操作等。也是把各种计算结果数据或信息以数字、字符、图像、声音等形式表现出来。常见的输出设备有显示器、打印机等

现代计算机中,运算器和控制器被合并在CPU里。储存器中的内存和外存,对应的也就是内存条和硬盘。

        那么在我们学习IO操作之前,我们所写的程序(代码)应该都只用到了计算机中的CPU和内存条。无论我们是创建一个数组、链表、对象还是别的什么,这些东西都只是在CPU和内存条中来回跑。可是我们计算机中的其它设备呢?我们如何对它们进行操作?

        为了解决这些问题,Java设计了一套与外部设备(硬盘、输入设备、输出设备)交互的框架,也就是IO框架。那么IO框架的工作原理是什么呢?它如何与外被设备进行交互呢?

        首先我们看看计算机与外部设备如何连接起来呢?通过数据线、网线等东西对吧,当然现在还有更高端的NFC、蓝牙之类的东西,但原理是一样的。它们之间连接起来之后,是通过特定的比特流进行沟通的。一个比特(bit)就表示一个二进制数,可以是0或者1。但是因为一个bit所表示的内容太有限了,所以计算机中更常见的基本单位是字节,一个字节由8个bit组成。当足够多的字节连续地从外部设备传入计算机、或者从计算机传入外部设备,这种情况就是比特流或者叫字节流,从外部设备传入的流称为输入流,从计算机传入的流称为输出流

        为了处理计算机的输入、输出流,Java给出了一套IO框架,它的工作原理也就是读取、写入流。Java中对应的抽象类就是InputStream和OutputStream。这俩就是我们对流进行操作的基础了。

        针对不同的外部设备,就会存在不同的IO流操作,为了方便理解我们就以硬盘这个外部设备为例子。(因为大家基本都是从读写本地数据开始接触IO流的,所以用这个做例子应该比较好理解吧。。。)在Java中其实不存在直接对“硬盘”的IO流操作,因为在Java虚拟机看来,我们面对的是一整个文件系统,也就是File对象。所以我们对硬盘的IO操作,本质上就是对File对象的读写。Java中有专门的FileInputStream和FileOutputStream,它们就是文件的输入、输出流。

        所有的流,它的基础都是字节流,字节流的本质就是一堆bit,它只有0和1两个值,可如果我们想要将一段文字写入File怎么办呢?你可能会说根据这些bit组成的二进制数,换算成对应的ASCii码来表示文字。这是没错的,可是你知道在Java中是如何将这些字节流转成文字的吗?答案就是:InputStreamReader、OutputStreamWriter。Reader和Writer的命名就知道,它们是用来读写的。它们将二进制的字节流转换为我们能直接看懂的东西,包括但不限于文字,这就将字节流转换为了字符流

        到了这个阶段,我们对于Java的IO框架已经有了基本的认识,直接实战IO操作也是莫得问题滴。但是在实际应用过程过程中,我们直接对流进行读取,这个速度其实是很慢的,因为字节流只能一个字节一个字节地读取,效率低下。为了更高效的读取流,Java提供了一个缓冲区的概念,BufferedInputStream、BufferedOutputSteam这两个类就是用来设置缓冲区的,这就使原本只能一个字节一个字节的读写突然变成了一段一段的读写,效率大大提升。

        说道这里,关于Java中流的基本操作就认识的差不多了。然后再回到我们刚刚说的文件系统(计算机中的硬盘),如果每次操作这些文件,我都得new 这么多xxxStream对象来操作,不是很累很费时间吗?有没有更方便的操作方式呢?有呀,各位前辈大佬们早就写好了。比如:FileReader和FileWriter,它们继承自InputStreamReader、OutputStreamWriter,都是Java中用于操作字符流的工具类。就像上一段说的,要想更高效的操作这些字符流,就需要使用到BufferedReader、BufferedWriter这两个类啦。

        那么到这里为止,对于Java的IO框架应该就有了更深的认识、更好的理解了,以后再深入学习,也不存在基础不牢靠的困境了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章