Java IO-整体了解
Java I/O 是什么?
首先要知道 I/O 是什么? I/O 是 Input/Output 的缩写,其实就是计算机系统中数据的输入/输出的过程。使用计算机时,键盘、硬盘是最常见的输入、输出设备,在这个过程中就会涉及 I/O。
Java 作为一种程序设计语言,需要提供程序与外部设备的交互方式,Java I/O 框架就是来解决这个问题的。
编程语言的 I/O 类库中常使用 流 这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象。“流” 屏蔽了实际的 I/O设备中处理数据的细节。Java 在流中读写数据的类分成输入和输出两部分,分别是任何由 InputStream 或 由Reader 和 OutputStream 或 Writer 派生而来的类。
Java I/O 框架有哪些东西?
打开 java.io 包会发现一堆的类和接口,从哪开始看呢?跟着《Java 编程思想》排版来看,看了一遍,也码了demo,总感觉只是知其然的程度。参考资料中的第二个链接,作者分析的思路很棒。
1. File 类
Java程序是运行在某操作系统平台上的应用软件JVM上的,实际上Java程序可见的并不是硬盘,而是操作系统提供的文件系统 。 学习IO流的时候, 基本上是学习Java如何操作文件系统,除了文件系统,我们还能够了解Java操作标准输入输出设备,如System.in和System.out。 要使用 Java 操作文件系统,首先要学习的就是文件的表示,即File类。
2. InputStream/OutputStream
API提供了两个顶层抽象类,用来表示操作所有的输出输出:InputStream,OutputStream。 这两个类表示字节的输入输出,因为输入输出的本质是字节流。这里注意体会一句话“字节流是最最基本的流”,这句话的由来就是因为计算机底层传递的就是字节。
当我们要操作文件的时候,就需要具体的对文件系统操作的IO实现类,于是我们需要学习FileInputStream和FileOutputStream,它们是文件输入输出字节流。 以此类推会有功能的输出输入流子类。
3. Reader/Writer
由于文件的分类和编码格式 , 人们需要有能够处理字符的类或者说这个类提供一个功能:就是把输入的字节转成字符,把要输出的字符转成计算机可以识别的字节。所以,你需要两个转换流:InputStreamReader 和 OutputStreamWriter。这两个类的作用分别是把字节流转成字符流,把字符流转成字节流。但是这两个流需要套在现成的字节流上才能使用,当中用到的设计模式也就是常说的装饰模式。 读写字符流顶层抽象类 : Reader 和 Writer 。
针对文件系统,FileReader 和 FileWriter 这两个流对象可以直接把文件转成读取、写入流。让你省去了创建字节流,再套上转换流的步骤。
4. 高效读写-缓冲流
原始的字节流对象用起来没那么高效,因为每个读或写请求都由底层操作系统处理,这些请求往往会触发磁盘访问、网络活动或其他一些相对昂贵的操作。不带缓冲区的流对象,只能一个字节一个字节的读,每次都调用底层的操作系统API,非常低效,而带缓冲区的流对象,可以一次读一个缓冲区,缓冲区空了才去调用一次底层API,这就能大大提高效率。所以又有了 BufferedInputStream 和 BufferedOutputSteam,它们的用法是把字节流对象传入后再使用,也相当于把它俩套在了字节流的外面,给字节流装了个“外挂”,让基本字节流如虎添翼。
把Reader和Writer做成高效的,就需要 BufferedReader 和 BufferedWriter,把它们套在Reader和Writer上,就能实现高效的字符流。
5. 其他流
还有许多类是“在内存里自己和自己玩的”比如:字节数组流( ByteArrayInputStream/OutputStream ,ByteArrayReader/Writer),管道流(PipedInputStream/OutputStream,PipedWriter/Reader),它们虽然也称为“流对象”但是它们的数据不出内存,所以它们的close()方法可有可无。
带有某些功能的类,比如序列化流(ObjectInputStream/OutputStream),比如数据输入输出流(DataInputStream/OutputStream),等等。
总结:字节流是基础,理论上可用于所有的输入输出场景,内容是文字的字节流可以通过转换流转成字符流,转换流是字节流和字符流之间相互转换的桥梁,把字节流转成字符流,离不开转换流,字符流是对于字符功能的增强可用来处理“文字”。操作文件系统应用范围最广,所以JDK提供了现成的FileXXX类,用来方便编程使用。 IO流对象的用法和作用大同小异,其使用环境和意义取决于具体需要,用到了再具体分析即可。
参考资料:
《Java 编程思想》
https://zhuanlan.zhihu.com/p/98094713
https://www.zhihu.com/question/67535292/answer/1248887503