一、IO流分类

1.基本划分和概念解释

  • 根据流的方向主要分为输入流和输出流两大类。
  • 根据数据流的单位的不同分为字节流和字符流。
  • 根据功能不同可以划分为节点流和处理流。

​节点流​​:可以从或向一个特定的地方(节点)读写数据。如FileReader

​处理流​​​:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
如BufferedReader。
(处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。)

下面主要从输入输出、字节字符两个分类来展开。

2.输入、输出

重识Java第十天打卡----IO流详解_缓冲池


从哪里输入输出?

  输入流是指从输入设备或文件或数据库输入数据到目的地。常见的输入设备比如键盘,目的地也同样可以是文件、数据库、内存等存储位置。

  输出流是指从流中读取数据,输出到文件、显示屏等位置。

对应关系

输入 — 读取
输出 — 写入

案例说明
下面以最简单的单个字节方式复制一个文件到另一个位置的案例展示输入输出关系。
代码如下:

import java.io.*;

public class Test {
public static void main(String[] args) throws IOException {
File f = new File("D:\\Desktop\\桌面\\泰戈尔诗十首.txt");

//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("Tagore.txt");

//创建字节输入流对象
FileInputStream fis = new FileInputStream(f);

//简化版
int by;
while ((by=fis.read())!=-1){
fos.write(by);
}

fis.close();
fos.close();
}
}

首先注意File文件类。
构造File对象时,既可以传入绝对路径,也可以传入相对路径。绝对路径是以根目录开头的完整路径。
但要注意不同系统的路径分隔符不同

  1. Windows平台使用​​\​​​作为路径分隔符,在Java字符串中需要用​​\\​​​表示一个​​\​​。
  2. Linux平台使用​​/​​作为路径分隔符。

下面是读取写入的过程

重识Java第十天打卡----IO流详解_缓冲池_02


一次读取单个字节是最慢的读写方式,效率低下的原因在于读取一个字节就会阻塞,读取成功后再进行写入,然后再读取。这样每次读取、写入一次就产生阻塞,使得阻塞不连续,导致效率降低。

3.字符 、字节

​字节流​​是最基础的方式,适用于所有文件类型的复制、转移等,但是对于读取中文输出会存在 ①乱码 or ②内存溢出 等问题。
​​​字符流​​则只适用于中文输出的情况,可以自己控制读取写入时的文件编码,从而解决中文乱码问题

二、缓冲流的应用

缓冲流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。

重识Java第十天打卡----IO流详解_缓冲池_03

1.为什么缓冲池有用?

因为缓冲池的存在,阻塞一次可以读取、写入更多的数据到缓冲池中。设要读取数据大小为 m 字节,缓存池大小为 n 字节,则只需阻塞 m/n 次。
详见:​​​【Java】缓冲流如何提高性能​

2.示例代码

BufferedReader

package JavaIOTest;


import java.io.*;

public class BufferedIoTest {
public static void main(String[] args) {
File file = new File("D:\Desktop\桌面\泰戈尔诗十首.txt");
//创建基于文件对象的字符流
//缓存流必须建立在一个存在的流的基础上
try(
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
)
{
while(true){
String line = bufferedReader.readLine();
if (null == line)
break;
System.out.println(linea);
}
}catch (IOException e){
e.printStackTrace();
}
}
}