序列化反序列化流_属性集合类_小记

来源:互联网 发布:幂学集训营怎么样 知乎 编辑:程序博客网 时间:2024/06/03 16:31

序列化是将一个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@273d6d53Star [name=刘诗诗, age=23]注:对象Star必须是实现了序列化接口Serializableimplements Serializable,否则会报错(NotSerializableException(没有实现序列化接口的异常)    )

序列化和反序列化版本号不一致,会出现InvalidClassException
*
* 解决这个异常两种方案:
* 1)要么改动当前某个类中的数据之后,然后重新序列化和反序列化
* 这种做法不符实实际要求,在实际开发中,可能直接读数据:将流数据—>还原成对象
* 2)发现黄色警告线,点击它:生成一个固定ID

序列化和反序列化考点:
* 1)将对象—>流数据或者流数据—>对象,该对象所在的类要实现一个标记接口:serializable 多线程有一个关键字:同步机制(synchronized)
* 2)序列化和反序列化生产的版本Id不一致的时候,会出现异常,所以使用生产随机ID或者固定ID解决
* 3)transient:修饰的变量不会被序列化…

注:反序列化机制无需通过构造器来初始化Java对象。使用序列化机制向文件写入多个Java对象,使用反序列化机制恢复对象必须按照实际写入的顺序读取


Properties:属性集合类,该类继承自Hashtable<K,V>,该类属于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<Object> po_keyset = po.keySet();        for(Object key : po_keyset){                System.out.println(key+"\t"+po.get(key));            }    }}

属性集合类:Properties有自己的遍历和添加元素的功能
* 给属性列表中添加元素:
* public Object setProperty(String key,String value)
* public Set<String> stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是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<Object> po_keyset = po.keySet();        for(Object key : po_keyset){                System.out.println(key+"\t"+po.get(key));            }    }}输出:3   刘诗诗2   abs1   2

属性集合类: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<String> 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<Object> pro_keyset = pro.keySet();        for(Object key: pro_keyset){            if(key.equals("Aoman")){                //修改                pro.setProperty((String)key, "35");            }        //存储数据            FileWriter fw = new FileWriter("d:\\Java\\Aoman_3.txt");            //文件输出:#//          #Fri Dec 01 16:24:20 CST 2017//          Aoman=35//          刘诗诗=23//          Alex=19//          荣蓉儿=20//          FileOutputStream fw = new FileOutputStream("d:\\Java\\Aoman_3.txt");//          //文件输出:#//          #Fri Dec 01 16:21:45 CST 2017//          Aoman=35//          \u00C1\u00F5\u00CA\u00AB\u00CA\u00AB=23//          Alex=19//          \u00C8\u00D9\u00C8\u00D8\u00B6\u00F9=20            pro.store(fw, "");        }    }}注:fileoutputstream输出的是字节,我们看到的也是字节,汉字是两个字节组成,会被拆开filewrite输出的是字符,我们会看到汉字。
原创粉丝点击