一.IO流概念
1.什么是IO流
在Java程序中用来处理设备之间的数据传输的工具.
程序读数据就用输入流, 写数据就用输出流.
2.流的分类
流按照处理数据的类型分为两种: 字节流, 字符流
流按照数据流向的类型分为两种: 输入流, 输出流
3.IO流的4个最大的抽象父类
Reader: 字符输入流
Writer: 字符输出流
InputStream: 字节输入流
OutputStream: 字节输出流
4.子类命名
FileInputStream 是 InputStream 的子类, 用来读取文件的字节输入流
FileReader 是 Reader 的子类, 用来读取文件的字符输入流
InputStreamReader 是 Reader 的子类, 用来从字节输入流中读取字符的流, 转换流
5.使用IO包中的类
使用前导包
使用时处理异常
使用后关闭流
二.字符流
1.逐个字符拷贝文件
使用FileReader的read()方法读取一个字符, 此方法读取到一个字符
使用FileWriter的write(int ch)方法写出一个字符
2.自定义数组拷贝文件
使用FileReader的read(char[] buf)方法读取一个数组
使用FileWriter的write(char[] buf, int off, int len)方法将数组中的数据写出, 指定从某个位置开始写, 写多少个
使用数组拷贝目的是为了尽量减少和文件打交道, 一次拷贝就多拷一些字符, 写出时一次也多写出一些.
3.使用带缓冲的输入输出流
使用BufferedReader的read()方法可以读取一个字符, 这个方法在第一次读取的时候会一次性读取8192个字符, 将其缓冲, 下次再读时从缓冲区中返回.
使用BufferedWriter的write(int ch)方法可以写出一个字符, 这个方法写出字符是先写出到缓冲区中, 直到缓冲区写满8192个之后, 才会真正写出.
4.逐行拷贝
使用BufferedReader的readLine()方法, 一次可以读取一行文本, 读的这行文本也是从缓冲区中获取的.
使用BufferedWriter的write(String s)方法, 一次写出一个字符串, 写出的字符串也是先写到缓冲区中.
三.包装设计模式
1.什么是包装设计模式
在使用一个类时, 发现这个类的功能不够强大, 对其进行包装, 在不改变原有功能的情况下, 增加新的功能.
2.包装设计模式的写法
定义一个成员变量, 持有一个被包装类对象的引用.
通过构造函数将一个被包装类的对象传入.
提供和被包装类相同的方法, 具有相同的功能.
在方法中调用被包装类的方法, 增加新功能, 使其更强大.
通常会继承被包装类或者和被包装类实现相同的接口, 这样我们的包装类就可以当做被包装类来使用了.
四.练习
1.编写程序, 自定义LineNumberReader, 将day14-笔记.txt拷贝到d盘根目录, 在每一行的开头加上行号.
2.有三个学生,每个学生有3门课的成绩,定义一种比较直观的文本文件格式,
输入学生姓名和成绩,从键盘输入以上数据(包括姓名,三门课成绩),
按总分数从高到低的顺序将学生信息存放在磁盘文件"stu.txt"中。
程序运行后, 提示用户输入信息:
张三,90,80,85
李四,80,80,70
王五,90,90,90
将学生信息存储到stu.txt中
王五,90,90,90,270
张三,90,80,85,255
李四,80,80,70,230
System.out.println("请输入学生信息:");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
TreeSet<Student> set = new TreeSet<Student>();
for (int i = 0; i < 3; i++) {
String line = reader.readLine(); // 获取用户输入
String[] info = line.split(",");
Student stu = new Student(info[0], Integer.parseInt(info[1]), Integer.parseInt(info[2]), Integer.parseInt(info[3]));
set.add(stu);
}
BufferedWriter writer = new BufferedWriter(new FileWriter("stu.txt"));
for (Student s : set)
writer.write(s.toString() + "/r/n");
writer.close();