文章目录
1、对象流
1.1、定义
功能:提供了对基本类型或对象类型的序列化和反序列化的方法
ObjectOutputStream 提供 序列化功能
ObjectInputStream 提供 反序列化功能
1.2、一览图
1.3、应用案例 1
使用ObjectOutStream 序列化基本数据类型和一个Dog对象(name,age),并保存到data.dat文件中
ObjectOutStream_.java
package outputstream_;
import java.io.*;
/**
* ObjectOutputStream 的使用, 完成数据的序列化
*/
public class ObjectOutStream_ {
public static void main(String[] args) throws IOException {
// 序列化后, 保存的文件格式, 不是存文本, 而是按照他的格式来保存
String filePath = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
// 序列化数据到 e:\data.dat
oos.writeInt(100); // int -> Integer (实现了 Serializable)
oos.writeBoolean(true); // boolean -> Boolean (实现了 Serializable)
oos.writeChar('a'); // char -> Character (实现了 Serializable)
oos.writeDouble(9.5); // double -> Double (实现了 Serializable)
oos.writeUTF("你好世界"); // String
// 保存一个 dog 对象
oos.writeObject(new Dog("旺财", 10, "日本", "白色"));
oos.close();
System.out.println("数据保存完毕(序列化形式)");
}
}
Dog.java
package outputstream_;
import java.io.Serializable;
public class Dog implements Serializable {
private String name;
private int age;
private String area;
private String color;
public Dog(String name, int age, String area, String color) {
this.name = name;
this.age = age;
this.area = area;
this.color = color;
}
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;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
1.4、应用案例 2
使用ObjectInputStream 读取 data.dat 并反序列化恢复数据
package inputstream_;
import outputstream_.Dog;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStream_ {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//指定反序列化的文件
String filePath = "e:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
// 读取
// 1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
// 2. 否则会出现异常
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
// dog 的编译类型是 Object, dog 的运行类型是 Dog
Object dog = ois.readObject();
System.out.println("运行类型=" + dog.getClass());
System.out.println("dog信息=" + dog); // 底层 Object -> Dog
// 这里是特别重要的细节:
// 1. 如果我们希望调用Dog的方法, 需要向下转型
// 2. 需要我们将Dog类的定义, 放在到可以引用的位置
Dog dog2 = (Dog) dog;
System.out.println(dog2.getName()); //旺财..
// 关闭流, 关闭外层流即可, 底层会关闭 FileInputStream 流
ois.close();
}
}
控制台输出
100
true
a
9.5
你好世界
运行类型=class outputstream_.Dog
dog信息=outputstream_.Dog@70177ecd
旺财
1.5、注意事项和细节说明
2、标准输入输出流
package standard;
import java.util.Scanner;
public class InputAndOutput {
public static void main(String[] args) {
// System 类 的 public final static InputStream in = null;
// System.in 编译类型 InputStream
// System.in 运行类型 BufferedInputStream
// 表示的是标准输入 键盘
System.out.println(System.in.getClass()); // class java.io.BufferedInputStream
// 解读
// 1. System.out public final static PrintStream out = null;
// 2. 编译类型 PrintStream
// 3. 运行类型 PrintStream
// 4. 表示标准输出 显示器
System.out.println(System.out.getClass()); // class java.io.PrintStream
System.out.println("hello, world");
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容");
String next = scanner.next();
System.out.println("next=" + next);
}
}
3、转换流-InputStreamReader 和 OutputStreamWriter
3.1、引出问题
先看一个文件乱码问题,引出学习转换流必要性
package transformation;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* 看一个中文乱码问题
*/
public class CodeQuestion {
public static void main(String[] args) throws IOException {
// 读取 e:\\a.txt 文件到程序
// 思路
// 1. 创建字符输入流 BufferedReader [处理流]
// 2. 使用 BufferedReader 对象读取 a.txt
// 3. 默认情况下, 读取文件是按照 utf-8 编码
String filePath = "e:\\a.txt";
BufferedReader br = new BufferedReader(new FileReader(filePath));
String s = br.readLine();
System.out.println("读取到的内容: " + s);
br.close();
// InputStreamReader
// OutputStreamWriter
}
}
3.2、定义
3.3、应用案例 1
编程将字节流 FileInputStream 包装成(转换成)字符流InputStreamReader,对文件进行读取(按照 utf-8/gbk 格式),进而在包装成 BufferedReader
package transformation;
import java.io.*;
/**
* 使用 InputStreamReader 转换流解决中文乱码问题
* 将字节流 FileInputStream 转成字符流 InputStreamReader, 指定编码 gbk/utf-8
*/
public class InputStreamReader_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\a.txt";
// 解读
// 1. 把 FileInputStream 转成 InputStreamReader
// 2. 指定编码 gbk
// InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
// 3. 把 InputStreamReader 传入 BufferedReader
// BufferedReader br = new BufferedReader(isr);
// 将 2 和 3 合在一起
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));
// 4. 读取
String s = br.readLine();
System.out.println("读取内容=" + s);
// 5. 关闭外层流
br.close();
}
}
3.4、应用案例 2
将字节流 FileOutputStream 包装成(转换成)字符流OutputStreamWriter,对文件进行写入(按照gbk格式,可以指定其他,比如 utf-8)
package transformation;
import java.io.*;
/**
* OutputStreamWriter 使用
* 把FileOutputStream 字节流, 转成字符流 OutputStreamWriter
* 指定处理的编码 gbk/utf-8/utf8
*/
public class OutputStreamWriter_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\test.txt";
String charSet = "utf-8";
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
osw.write("hi, 张三");
osw.close();
System.out.println("按照 " + charSet + " 保存文件成功~");
}
}