目录
1. 什么是 IO 流
流是个抽象的概念,是对输入输出设备的抽象。Java 程序中,对于数据的输入/输出操作都是以 “ IO 流” 的方式进行,设备可以是文件、网络、内存等。流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,则称为输出流,反之称为输入流。可以将流想象成一个“水流管道”,每次需要读写数据时,都会在设备与程序之间建立一条用来传输数据的管道,数据就像水流一样从设备流向程序(读),或者从程序流向设备(写)。
数据在计算机中都是以二进制的形式存储。拿 .txt 文件来说,它的数据就是以二进制的形式存储于计算机的硬盘之中。若此时用记事本打开这个文件,实际上就是在记事本与 .txt 文件之间建立了数据流,然后这些二进制数据源源不断的流向记事本,并在记事本中根据各种编码表转化为相应的字符:如 97 在文件中以二进制 01100001 存储,读入记事本中对照 ASCⅡ 编码表转化为字符 'a' 显示在记事本中。
2. IO 流的分类
Java 中定义了许多类专门负责各种方式的输入或者输出,这些类都被放在 java.io 包中。按照传输数据类型的不同,大体上分为两类:一类是针对二进制文件的字节流,另一类是针对文本文件的字符流。其中,所有的字节流类都继承了输入流 InputStream 类和输出流 OutputStream 类;而所有的字符流类都继承了输入流 Reader 类和输出流 Writer 类。这两种流最大的不同就在于字节流是以字节为单位进行数据传输的,而字符流是以字符为单位进行数据传输。
3. IO 流相关概念
- 节点流:可以从或向一个特定的地方(节点)读写数据。
- 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
Java常用的节点流:
- 文件流:对文件进行处理的节点流。如 FileInputStream、FileOutputStrean、FileReader、FileWriter。
- 字符串流: 对字符串进行处理的节点流。如 StringReader、StringWriter。
- 数组流:对内存中的数组数据进行处理的节点流。如 ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter。
- 管道流:对管道进行处理的节点流。如 PipedInputStream、PipedOutputStream、PipedReaderPipedWriter。
Java常用的处理流:
- 缓冲流:增加缓冲区,避免频繁读写硬盘。如 BufferedInputStrean、BufferedOutputStream、BufferedReader、BufferedWriter。
- 转换流:实现字节流和字符流之间的转换。如 InputStreamReader、OutputStreamReader。
- 数据流:能读写基础数据类型( 如 int、long、double 等 )。如 DataInputStream、DataOutputStream。
缓冲区的概念:
缓冲区就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区。举个简单的例子:一个人要把砖头从 A 地搬到相隔很远的 B 地,就必须一块一块的搬,很费时费力;此时如果有一辆卡车,那么就只需要在 A 地把所有砖头装上卡车直接运到 B 地,这就节省了很多的人力并且提高了效率。
缓冲区正好充当了卡车的作用,CPU 从内存中的缓冲区读取数据比直接去硬盘读取数据要快得多,并且缓冲区在内存中被预先创建且可重复使用,提高了内存空间了复用率,减少动态分配和回收内存的次数。但需要注意的是,缓冲区必须在存满之后才能被读或者写,也就是说每次读写操作必须等到缓冲区被充满才能够执行,执行完释放缓冲区再重复执行。
在 Java 的 IO 流中,缓冲区一般为一个 1024 倍数大小容量的 byte 或 char 类型的数组,而数据类型则取决于是字节流还是字符流。