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

序列化是将一个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 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 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 po_keyset = po.keySet();
        for(Object key : po_keyset){
                System.out.println(key+"\t"+po.get(key));
            }

    }

}
输出:
3   刘诗诗
2   abs
1   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 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 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输出的是字符,我们会看到汉字。 
  

                            
                        
                    
                    
                    

你可能感兴趣的:(序列化反序列化流_属性集合类_小记)