3.1 缓冲流 转换流 打印流
3.1.1 缓冲流
之前我们学习了一些基本的流,其实只是作为我们 IO 系列的入门知识,都很简单。但是IO系列还有更多更强大的流。比如能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建而来的,相当于给一个普通的人穿上防弹衣,配置好武器,立马战斗力暴增,相当于是对基本流对象的一种增强。
缓冲流 的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统 IO 次数,从而提高读写的效率。内存中的数据本来是 一点儿一点儿刷到 硬盘上的,但是有了缓冲区 后,就先把数据 刷到了 缓冲区,而缓冲区是内存里的一块空间,所以进行数据交换效率极高,然后当数据 传到缓冲区一定量的时候,缓冲区 一次性 刷到 硬盘上。是很高效的。
① BufferedReader(Reader in)
创建一个 新的 缓冲 输入流
② BufferedWriter(Writer out)
创建一个 新的 缓冲 输出流
字符缓冲流 的 基本方法 与 普通字符流 调用方式 是一致的,因为 这个缓冲流 就是一个 装饰类。
BufferedReader.readLine() :读一行字符(文本内容)
BufferWriter.newLine() : 写一行 行分隔符,由 系统属性 定义 符号。大白话就是 根据你的操作系统 决定你写文本内容时 回车 之后的 符号是啥。然后创建 这个 符号,达到 回车换行的效果!!!
其实 我们在 一般情况下,缓冲流 这玩意 就是作为 行读取 和 写回车换行 来用的。我们如果要是 想弄什么 缓冲区的话,还不如 自己 new 一个 数组,自己来玩。
import java.io.*;
public class Buffer {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("test.txt");
fw.write("大撒大撒打算大苏打按时\n" +
"大撒大撒打算大苏打按时");
fw.close();
BufferedReader bufferedReader = new BufferedReader(new FileReader("test.txt"));
String str = null;
while((str = bufferedReader.readLine()) != null){
System.out.println(str);
}
bufferedReader.close();
}
}
3.2.1 转换流
转换流是因为什么 诞生的呢 ?
答:虽然 计算机中 储存的信息 本质都是二进制,但是我们 能够看到的 数字、英文、标点、符号、汉字 等等 字符 都是通过 某种解析 将 二进制 转换后渲染出来的结果。那么 按照 某种规则,将字符存储到 计算机中!我们称之为 编码
,反之 将 计算机中的二进制 按照某种规则解析出来的过程,我们称之为 解码
。比如说,按照 A 规则存储,同样我们就要按照 A 规则解析。才能够得到 正确的文本 符号。反之,我们说 按照 A 规则存储,然后却按照 B 规则解析,那肯定就会出现乱码现象呀!这也是我们 常说的 乱码。
由此 转换流 就诞生了(也属于 装饰类的一种)
① InputStreamReader(InputStream in,String charsetName)
这是 创建一个 输入转换流
② OutputStreamWriter(OutputStream out,String charsetName)
这是 创建一个 输出转换流
来 大家 看下 典型的 乱码问题:
因为 我们 默认是 按照 UTF-8 去 解析和编码的,当你设置为 GBK 的编码 写的文件,再去用 UTF-8 去读,那就肯定 有乱码问题!!
import java.io.*;
public class 转换流 {
public static void main(String[] args) throws IOException {
OutputStreamWriter opsw = new OutputStreamWriter(new FileOutputStream("test.txt"),"GBK");
BufferedWriter bw = new BufferedWriter(opsw);
bw.write("我是GBK 编码 的字符串!");
bw.close();
opsw.close();
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt"),"GBK"));
String str = null;
while((str = br.readLine()) != null){
System.out.println(str);
}
br.close();
}
}
3.3.1 打印流
这个打印流 的话,说人话就是 黑底白字的那个控制台,也就是 System.in
和 System.out
。我们都知道 在默认 情况下 它 分别代表 键盘接收的数据文件 和 显示器显示的数据文件。其实 程序 就是 通过 System.in 来获取 你键盘 输入的数据的。就是 用一个 输入流。然后 打印的那个 API,也 是 试图 通过 System.out 用 一个 输出流 来 调出 数据,显示在 屏幕上!它的底层 就是打印流。只不过,只不过 System.in
和 System.out
你可以把它俩当作一个 特殊的 文本文件。
当我们 学习了 IO 流 之后,我们就要知道 平常说的 标准输入输出 也是 要靠这个 IO 流的。这个流 就是 打印流 和 输入流 一起配合这来的。
PrintStream(OutputStream out)
可以 把一个 输出流 包装为 一个 打印流。
System.setOut(打印流)
配合着 System 这个 setOut 方法,就把 我们的 系统 输出 给 改动了。
这个时候 我们输出 就不会 再 固定的 输出到 cmd 那个 窗口上了,或者说 不会 输出 到 屏幕上了。。
PrintStream.println()
当然 直接 调用 这个 打印流的 方法 其实更好。。更方便。。哈哈 ~ ~
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class 打印流 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream prout = new PrintStream(new FileOutputStream("test.txt"));
System.setOut(prout);
System.out.println("我输出了");
System.out.println("我输出了");
prout.println("这样输出 更方便");
prout.close();
}
}
System.setIn(输入流)
同理 如果 我们 有这个 方法,就可以 设计出来 标准的 输入输出流了。
这个 就是 设置系统的 输入流是哪个。
但是这个 我就不做 演示了,很简单的。