一、缓冲流(高效流)
1.缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
2.原理
缓冲流创建对象的时候,有一个缓冲区数组,通过缓冲区数组读取,效率大大提升
3.字符缓冲流需注意的两个方法
BufferedReader: public String readLine() : 读一行文字。
BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。
基础练习
对以下文本按序号排序(注意每个数字后面的文本必须在一行)
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
9.今当远离,临表涕零,不知所言。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
package cn.itcast.test;
import java.io.*;
import java.util.HashMap;
import java.util.Set;
public class Test {
public static void main(String[] args) throws IOException {
//创建map来存储数据信息
HashMap<String, String> map = new HashMap<>();
//创建缓冲字符输入流,读取数据到内存(或者程序)
BufferedReader br = new BufferedReader(new FileReader("day10\\file.txt"));
//创建缓冲字符输出流,写数据到另一文件
BufferedWriter bw = new BufferedWriter(new FileWriter("day10\\chengeFile.txt"));
//读取数据
String line;
while ((line = br.readLine()) != null) {
String[] split = line.split("\\.", 2);
map.put(split[0], split[1]);
}
Set<String> set = map.keySet();
for (int i = 1; i <= set.size(); i++) {
//写入数据
String str = i + "." + map.get(i+"");
bw.write(str);
bw.newLine();
}
br.close();
bw.close();
}
}
二、转换流
1.编码?
字符 按照一定的规则 变为字节;
2.解码?
字节 按照一定的规则 变为 字符;
3.为什么会发生乱码?
编码和解码的规则不一样;
4.常见字符码表?
ASCII码表:
GBK;(一个汉字占用两个字节)
UTF-8;(一个汉字占用三个字节)
ISO-8859-1:
5.转换流能解决什么问题?
乱码问题
由于转换流可以指定编码表,那么它就可以保证我们读写的时候(编码和解码的规则一样);
三、序列化流
1. 一个对象要想序列化,必须满足两个条件:
a.该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任
何状态序列化或反序列化,会抛出 NotSerializableException 。
b.该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
transient 关键字修饰。
2.反序列化操作
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用 ObjectInputStream 读取对象的方法:
public final Object readObject () : 读取一个对象。
当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操
作也会失败,如果需要修改,则必须给序列化类一个版本号serialVersionUID
3.重要总结
如果一个class在反序列化前被修改,但是我还想要得到反序列化修改之后的class,那么在序列化之前,我需要给这个类添加序列化版本serialVersionUID
序列化练习
1. 将存有多个自定义对象的集合序列化操作,保存到 list.txt 文件中。
2. 反序列化 list.txt ,并遍历集合,打印对象信息。
Person类
package cn.itcast.test01;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -8289499667595781797L;
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Test类
package cn.itcast.test01;
import java.io.*;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1. 将存有多个自定义对象的集合序列化操作,保存到 list.txt 文件中。
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("张三",20));
list.add(new Person("李四",21));
list.add(new Person("王五",23));
//把集合对象序列化到list.txt文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10\\list.txt"));
oos.writeObject(list);
//2. 反序列化 list.txt ,并遍历集合,打印对象信息。
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10\\list.txt"));
Object o = ois.readObject();
ArrayList<Person> list1 = (ArrayList<Person>)o;
for (Person person : list) {
System.out.println(person);
}
}
}
IO流总结