IO概述
我们知道数据会在内存和硬盘之间交互,先来看一个图:
对于数据的输入和输出,是参照内存而言的。内存中的数据写入硬盘,即相对于内存是输出(Output),为写(write),而硬盘写入内存,则为输入(Input),为读(read)。因为在数据在管道中传输,相当于发生了数据的流动,即有了对应的输出流(OutputStream)和输入流(InputStream)。
1.什么是IO?
I/O是Input/Output的缩写。通过IO操作可以完成对硬盘文件的读和写。
2.IO的分类
-
根据数据流的流动方向:
- 内存中流向硬盘中,称为:输出流;
- 硬盘中流向内存,称为:输入流。
-
根据读取数据的方式:
-
字节流:一次读取一个字节,即八个二进制位。字节流是万能流,可以用于读取文本文件、图片、音频、视频等。
-
字符流:每次读取一个字符。字符流只能读取普通的文本文件,其就是为了方便读取文本文件的。
(注意:word是有格式的,不属于普通文本文件,可以简单理解为普通文本文件可以用记事本打开,但不一定是txt结尾。)
例:
一个txt文本中的内容为:a中b国c人
采用字符流的方式读取:第一次读a,第二次读中,第三次读b......
采用字节流的方式读取:第一次读a,第二次读中的一半,第三次读中的另外一半,第四次读b......
这里需要注意的是:
读取的字节和字符是相对于Windows系统而言的,在Windows系统中,一个英文字符是一个字节,一个中文是两个字节,所以读取汉字时,每次只能读一半。(区别于Java中char为两个字节,不要混淆了!)
-
3.IO的四大家族
Java中的IO流都已经写好了,不需要我们去写。简而言之,我们需要做的就是了解IO中有哪些流操作的类,它们的特点是什么,并且要学会如何去使用它们,是字节流还是字符流,怎么new对象,怎么读,怎么写,其它常用方法是什么。(面向api文档学习)
Java中的流的类都在java.io下,即java.io.*;
Java中的流主要分为四大家族:字节输入流(InputStream)、字节输出流(OutputStream)、字符输入流(Writer)、字符输出流(Reader)。
以Stream结尾的为字节流,以Reader或者Writer结尾的为字符流。
并且四大家族有一些共同的特点:
-
都为抽象类;
-
都实现了closeable接口,所以都拥有close(),用于操作之后关闭流,释放资源;
(流毕竟是一个管道,用于内存和硬盘之间的通道,如果不关闭的话,会消耗很多的资源,所以用后一定要关闭)
-
其中输出流OutputStream、Writer还实现了flushable接口,所以拥有flush(),flush()的作用是将管道中剩余未输出的数据强行清空,在写入数据时,最后使用flush()将管道中可能剩余的数据全部写到硬盘文件中,如果没有flush(),就有可能丢失一部分数据。
(所有的输出流都拥有flush(),并且一定要进行此操作,防止数据的丢失)
4.需要学习掌握的16个流
因为Java四大家族的首领都是抽象类,所以它们拥有很多的子类,我们学习也是学习它们的子类,主要学习以下16个:
-
文件操作流:FileInputStream、FileOutPutStream、FileWriter、FileReader;
-
转换流:InputStreamReader、InputStreamWriter;
(注意,转换流虽然有Stream也有Reader/Writer,但是是看什么结尾的,所以转换流是字符流,就是将字节流转换为字符流的。)
-
缓冲流:BufferedInputStream、BufferedOutPutStream、BufferedWriter、BufferedReader;
-
数据流:DataInputStream、DataOutputStream;
-
对象流:ObjectInputStream、ObjectOutputStream;
-
标准输出流:PrintStream、PrinterWriter。
虽然看着很多(实际好像也真的很多),但是只要学习了其中的一对输入输出,只要了解其特性,其它基本都是照葫芦画瓢了。