序列化是将一个Java对象写入IO流中,形成二进制流,可以间接的把对象
保存在磁盘中,或者允许在网络中直接传输对象(在网路上传输的类必须是可序列化的)
反序列化是从IO流中恢复该Java对象
序列化流:将对象像流的方式或者网络传输中的数据写数据.对象—->流数据:ObjectOutputStream
* 反序列化:将流数据或者网络传输中的流数据读取出来.流数据—->还原成对象:ObjectInputStream
*
* ObjectOutputStream中的成员方法:
* public final void writeObject(Object obj):将obj对象写入到当前的序列化流中
* ObjectInputStream中的成员方法:
* public final Object readObject():从当前反序列化流中读取一个对象
注:要先序列化,在反序列化,不可颠倒,否则报错
(java.io.StreamCorruptedException: invalid stream header: CEAAC8CB)
package Day19_System;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import Day19_DataInOutput.Star;
/**
* @author Aoman_Hao
*/
public class ObjectWriterTest {
public static void main(String[] args) throws IOException,
FileNotFoundException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("d:\\Java\\JavaTest\\Aoman_Hao.txt"));
Star s1 = new Star("刘诗诗", 23);
oos.writeObject(s1);
System.out.println(oos);
oos.close();
// 读取数据
FileInputStream fis = new FileInputStream(
"d:\\Java\\JavaTest\\Aoman_Hao.txt");
//
ObjectInputStream ois = new ObjectInputStream(fis);
// 反序列化,流数据读取出来,流数据---->还原成对象
// Object readObject = ois.readObject(); //默认object类
Star readobject = (Star)ois.readObject(); //强转为Star类
ois.close();
System.out.println(readObject);
}
}
输出:
java.io.ObjectOutputStream@273d6d53
Star [name=刘诗诗, age=23]
注:对象Star必须是实现了序列化接口Serializable
implements Serializable,否则会报错(NotSerializableException(没有实现序列化接口的异常) )
序列化和反序列化版本号不一致,会出现InvalidClassException
*
* 解决这个异常两种方案:
* 1)要么改动当前某个类中的数据之后,然后重新序列化和反序列化
* 这种做法不符实实际要求,在实际开发中,可能直接读数据:将流数据—>还原成对象
* 2)发现黄色警告线,点击它:生成一个固定ID序列化和反序列化考点:
* 1)将对象—>流数据或者流数据—>对象,该对象所在的类要实现一个标记接口:serializable 多线程有一个关键字:同步机制(synchronized)
* 2)序列化和反序列化生产的版本Id不一致的时候,会出现异常,所以使用生产随机ID或者固定ID解决
* 3)transient:修饰的变量不会被序列化…
注:反序列化机制无需通过构造器来初始化Java对象。使用序列化机制向文件写入多个Java对象,使用反序列化机制恢复对象必须按照实际写入的顺序读取
Properties:属性集合类,该类继承自
Hashtable
,该类属于Map集合
* Properties 类表示了一个持久的属性集。
* Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串(一般情况:它用作配置文件去使用,MySQL或者Oracle中用它做配置文件)
* 构造方法:
* public Properties():创建一个空属性列表
package Day19_properies;
import java.util.Properties;
import java.util.Set;
/**
* @author Aoman_Hao
*/
public class PropertiesTest {
public static void main(String[] args) {
//创建properties集合
Properties po = new Properties();
po.put(1, 2);
po.put(2, "abs");
po.put(3, "刘诗诗");
//遍历
Set
属性集合类:Properties有自己的遍历和添加元素的功能
* 给属性列表中添加元素:
* public Object setProperty(String key,String value)
* public SetstringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
* public String getProperty(String key)用指定的键在此属性列表中搜索属性值
package Day19_properies;
import java.util.Properties;
import java.util.Set;
/**
* @author Aoman_Hao
*/
public class PropertiesTest {
public static void main(String[] args) {
//创建properties集合
Properties po = new Properties();
po.put(1, 2);
po.put(2, "abs");
po.put(3, "刘诗诗");
//遍历
Set
属性集合类:Properties有自己的遍历和添加元素的功能
* 给属性列表中添加元素:
* public Object setProperty(String key,String value)
(setProperty调用 Hashtable 的方法 put,强制要求为属性的键和值使用字符串)
* public Set stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
* public String getProperty(String key)用指定的键在此属性列表中搜索属性值
注:此类是线程安全的:多个线程可以共享单个 Properties 对象而无需进行外部同步
package Day19_properies;
import java.util.Properties;
import java.util.Set;
/**
* @author Aoman_Hao
*/
public class PropertiesTest2 {
public static void main(String[] args) {
// 创建集合类
Properties po = new Properties();
// 添加元素到集合里,调用hashtable的put方法,强制要求为属性的键和值使用字符串
po.setProperty("刘诗诗", "23");
po.setProperty("Aoman", "30");
po.setProperty("荣蓉儿", "20");
// 获得键的集合
Set spn = po.stringPropertyNames();
// 字符缓冲区append拼接,遍历
StringBuffer sb = new StringBuffer();
for (String key : spn) {
sb.append("姓名:").append(key).append("\t年龄:")
.append(po.getProperty(key)).append("\r\n");
}
System.out.println(sb);
}
}
输出:
姓名:Aoman 年龄:30
姓名:刘诗诗 年龄:23
姓名:荣蓉儿 年龄:20
注:尽量用stringbuffer拼接,少用string和+拼接,这样可以节省资源
Properties 可保存在流中或从流中加载。
* 将文件中的数据加载到属性集合中:public void load(Reader reader)
* 将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)
* 第二个参数:comments:对当前属性列表 的描述
package Day19_properies;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import Day19_DataInOutput.Star;
/**
* @author Aoman_Hao
*/
public class PropertiesTest3 {
public static void main(String[] args) throws IOException {
//先保存,在加载
//store保存
Properties pro = new Properties();
pro.put("刘诗诗","23" );
pro.put("Aoman","33" );
pro.put("荣蓉儿","20" );
pro.put("Alex","19" );
//将属性列表中的数据保存到文件中public void store(Writer writer,String comments)
FileOutputStream fos = new FileOutputStream("d:\\Java\\Aoman_3.txt");
pro.store(fos, "姓名年龄");
pro.clone();
//输出到文件:
// #\u59D3\u540D\u5E74\u9F84
// #Fri Dec 01 15:19:19 CST 2017
// Aoman=33
// \u5218\u8BD7\u8BD7=23
// Alex=19
// \u8363\u84C9\u513F=20
//加载
//创建属性集合类
Properties pro2 = new Properties();
//创建输入流
FileInputStream fis = new FileInputStream("d:\\Java\\Aoman_3.txt");
//加载
pro2.load(fis);
System.out.println(pro2);
fis.close();
//输出:
// {Aoman=33, 刘诗诗=23, Alex=19, 荣蓉儿=20}
}
}
用properties属性集合load,store,遍历来修改文件内容
package Day19_properies;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/**
* 修改Aoman的年龄由33为35岁
* @author Aoman_Hao
*/
public class PropertiesTest4 {
public static void main(String[] args) throws IOException{
//通过properties属性集合修改内容
//创建属性集合,输入流
Properties pro = new Properties();
FileInputStream fis = new FileInputStream("d:\\Java\\Aoman_3.txt");
//读取流数据
pro.load(fis);
fis.close();
//遍历
Set