一、序列化
1.概述
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
2.使用方法
对象序列化流: ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
-
对象反序列化流: ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
-
注意
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
-
构造方法
方法名 说明 ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream -
对象方法
方法名 说明 void writeObject(Object obj) 将指定的对象写入ObjectOutputStream Object readObject() 从ObjectInputStream读取一个对象 User类
:serialVersionUID&transient的使用
import java.io.Serializable;
//如果想要这个类的对象能被序列化,那么这个类必须要实现一个接口.Serializable
//Serializable 接口的意义
//称之为是一个标记性接口,里面没有任何的抽象方法
//只要一个类实现了这个Serializable接口,那么就表示这个类的对象可以被序列化.
public class User implements Serializable {
//serialVersionUID 序列号
//如果我们自己没有定义,那么虚拟机会根据类中的信息会自动的计算出一个序列号.
//问题:如果我们修改了类中的信息.那么虚拟机会再次计算出一个序列号.
//第一步:把User对象序列化到本地. --- -5824992206458892149
//第二步:修改了javabean类. 导致 --- 类中的序列号 4900133124572371851
//第三步:把文件中的对象读到内存. 本地中的序列号和类中的序列号不一致了.
//解决?
//不让虚拟机帮我们自动计算,我们自己手动给出.而且这个值不要变.
private static final long serialVersionUID = 1L;
private String username;
private transient String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
测试存取对象
static void method1() throws IOException, ClassNotFoundException {
User user = new User("zhangsan","qwer");
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(user);
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
User o = (User) ois.readObject();
System.out.println(o);
ois.close();
}
测试存取集合
static void test() throws IOException, ClassNotFoundException {
//1.创建集合
ArrayList<Student> arrayList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Student s = new Student("佟丽娅:"+ String.valueOf(i),30+i);
arrayList.add(s);
}
//2.将集合对象序列化到文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
oos.writeObject(arrayList);
oos.close();
//3.将文件中的对象数据,读取到内存中
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
Object obj = ois.readObject();
ois.close();
//取出集合对象
ArrayList<Student> arrayList1 = (ArrayList<Student>)obj;
for (Student s : arrayList) {
System.out.println(s.getName() + "," + s.getAge());
}
}
二、Properties集合
1、概述
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
2、常用方法
方法名 | 说明 |
---|---|
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set<String> stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
public synchronized V put(K key, V value) | 设置集合的键和值 |
public Set<K> keySet() | 从该属性列表中返回一个不可修改的键集 |
static void test1(){
// Properties<String,String> prop = new Properties<String,String>(); //错误
Properties prop = new Properties();
//设置集合的键和值,都是String类型
for (int i = 0; i < 3; i++) {
prop.setProperty("佟丽娅:"+ String.valueOf(i), String.valueOf("年龄" + i));
}
for (int i = 3; i < 6; i++) {
prop.put("佟丽娅:"+ String.valueOf(i),30+i);
}
//使用此属性列表中指定的键搜索属性
System.out.println(prop.getProperty("佟丽娅:3"));
System.out.println(prop);
//遍历集合
Set<Object> keySet = prop.keySet();
for (Object key : keySet) {
Object value = prop.get(key);
System.out.println(key + "," + value);
}
//从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
Set<String> names = prop.stringPropertyNames();
for (String key : names) {
String value = prop.getProperty(key);
System.out.println(key + "," + value);
}
}
3Properties和IO流相结合
-
和IO流结合的方法
方法名 说明 void load(Reader reader) 从输入字符流读取属性列表(键和元素对) void store(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流
private static void test2() throws IOException {
Properties prop1 = new Properties();
for (int i = 0; i < 3; i++) {
prop1.setProperty("佟丽娅:"+ String.valueOf(i), String.valueOf("年龄" + i));
}
// 创建文件
FileWriter fw = new FileWriter("fw.txt");
// 保存Properties对象
prop1.store(fw,null);
fw.close();
Properties prop2 = new Properties();
// 读取文件
FileReader fr = new FileReader("fw.txt");
// 读取Properties对象
prop2.load(fr);
fr.close();
System.out.println(prop2);
}