今天我们来聊聊IO操作之-----------------字符流
Reader和Writer它们都是抽象类,所以要使用它们的子类
InputStreamReader和OutputStreamWriter
1.OutputStreamWriter
继承关系
用字符流向文件中写入数据
public class TestWrite {
public static void main(String[] args) throws Exception {
//创建流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\hello.txt",true));
//准备数据
String s = "1208早上好";
//写数据
osw.write(s);
//关闭资源
osw.close();
}
}
2.InputStreamReader
继承关系
public class TestRead {
public static void main(String[] args) throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\hello.txt"));
int r = 0;
while(-1 != (r = isr.read())) {
System.out.println((char)r);
}
isr.close();
}
}
3.字节转字符流(编码格式)
4.复制文本文件,使用字符流不能复制非文本文件
此方法效率特别低
public class TestCopy {
public static void main(String[] args) throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\j.png"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:\\j.png"));
int r = 0;
while(-1 != (r = isr.read())) {
osw.write(r);
}
osw.close();
isr.close();
}
}
高效率的复制文本文件(重要)
示例代码:
//高效率复制文本文件
public class TestCopy2 {
public static void main(String[] args) throws Exception {
InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\hello.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:\\hello.txt"));
char[] cbuf = new char[1024];
int len = 0;
while(-1 != (len = isr.read(cbuf))) {
osw.write(cbuf, 0, len);
}
osw.close();
isr.close();
}
}
5.缓冲流
使用缓冲流复制文本文件
内部也是字符数组,内部进行读写时也要相互转化,所以效率没直接定义字符数组存取效率高。
示例代码
public class TestCopy3 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\hello.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\hello.txt")));
String line = null;
while(null != (line = br.readLine())) {
bw.write(line);
bw.newLine();//表示和系统相关的换行符
}
bw.close();
br.close();
}
}
6.序列化与反序列化
序列化:把对象保存在硬盘中,使用ObjectOutputStream其中的writeObject方法
ObjectOutputStream继承关系:
反序列化:把对象从硬盘中读取出来,使用ObjectInputStream其中的readObject方法
ObjectInputStream继承关系:
序列化对象之前必须让实体类实现Serializable接口
Serializable接口既没有属性,也没有方法,我们把这种接口称为标志性接口
1.将对象序列化到内存中
public class TestWriteObject {
public static void main(String[] args) throws Exception {
//java要求,如果想让一个类被序列化,需要让该类实现Serializable接口
//Serializable接口既没有属性,也没有方法,我们把这种接口称为标志性接口
Dog dog = new Dog("旺财", 2, "黑色");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\dog.txt"));
oos.writeObject(dog);/ere/一次只能写入一个对象,如果想写入多个对象需要放到集合中
oos.close();
}
}
2.把对象从硬盘中反序列化到内存中
public class TestReadObject {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\dog.txt"));
Dog dog = (Dog) ois.readObject();//读取对象,返回值类型是Object类型,需要向下类型转换
System.out.println(dog);
ois.close();
}
}
特别注意:如果修改了序列化对象对应类的结构,就不能反序列化了
原理:当序列化时会根据类的结构计算一个值UID,当反序列化时又会计算一个UID值,拿两个值进行比较,如果一致可以成功反序列化,否则不能反序列化
在实体类的属性前手动生成UID
private static final long serialVersionUID = 1L;
如果不希望某些数据被反序列化,可以添加transient关键字
private transient String color;
3.将集合序列化到硬盘中
public class TestWriteBook {
public static void main(String[] args) throws Exception {
ArrayList<Book> books = new ArrayList<Book>();
books.add(new Book("java大全1", "张老师1", 8001));
books.add(new Book("java大全2", "张老师2", 8002));
books.add(new Book("java大全3", "张老师3", 8003));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\books.txt"));
oos.writeObject(books);
oos.close();
}
}
public class TestReadBook {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\books.txt"));
ArrayList<Book> books = (ArrayList<Book>) ois.readObject();
System.out.println(books);
ois.close();
}
}
7.使用BufferedReader替代Scanner
System.in标准的输入流,可以把键盘的数据保存在流中
System.out标准的打印流,可以把流中的数据输出到屏幕上
可以使用BufferedReader替代Scanner
示例代码:
public class TestRead4 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入姓名");
String name = br.readLine();
System.out.println("name=" + name);
br.close();
}
}
Io字符流就介绍这么多了,对字符流其他方法操作还不太熟练的小可爱们,可以看看官方API文档
记得点赞+关注👉: 本人github地址:https://github.com/Lmobject