moc 发表于 2019-1-11 17:40:39

Java-029 IO流之序列化与Properties

1、序列化
序列化:可以把对象写入文本文件或者在网络中进行传输。
序列化流--->把对象按照流一样的方式存入文本文件或者在网络中传输; 对象 --> 流数据(ObjectOutputStream)
反序列化流 --->把文本文件中的流对象数据或者网络中的流对象数据还原成对象; 流数据 --> 对象(ObjectInputStream)
整个过程都是 Java 虚拟机(JVM)独立完成的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。
基本方法:
public ObjectOutputStream(OutputStream out) -----------> 创建写入指定 OutputStream 的 序列化流
public final void writeObject(Object x) ---------------------> 将指定的对象写入序列化流
public ObjectInputStream(InputStream in)--------------->创建从指定 InputStream 读取的反序列化流,并从流读取头部并予以验证
public final Object readObject()---------------------------->从 反序列化流读取对象
NotSerializableException:未序列化异常
        ① 类通过实现 java.io.Serializable 接口以启用其序列化功能。
        ② 未实现此接口的类将无法使其任何状态序列化或反序列化。
        ③ 该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口。
        ④ 反序列化的对象必须要提供该对象的字节码文件.class。
        ⑤Person类实现了序列化接口,那么它本身也应该有一个标记值,在修改java文件的内容的时候,其class文件的id值都会发生改变,需要手动指定固定的ID(黄色警告线)。
                private static final long serialVersionUID = xxxxxx;
        ⑥ 使用transient关键字声明不需要序列化的成员变量。
类实现序列化接口:
import java.io.Serializable;
public class Person implements Serializable {
        private static final long serialVersionUID = -202548545620344L;

        private String name;
        private transient int age;

        public Person() { super(); }

        public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
        }

        public String getName() { return name; }

        public void setName(String name) { this.name = name; }

        @Override
        public String toString() {
                return "Person ";
        }
} 序列化和反序列化操作:
public static void main(String[] args) throws IOException,ClassNotFoundException {
        write();
        read();
}

private static void write() throws IOException {
        // 创建序列化流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));

        // 创建对象
        Person p = new Person("林青霞", 27);

        // public final void writeObject(Object obj)
        oos.writeObject(p);

        // 释放资源
        oos.close();
}

private static void read() throws IOException, ClassNotFoundException {
        // 创建反序列化对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));

        // 还原对象
        Object obj = ois.readObject();

        // 释放资源
        ois.close();

        // 输出对象
        System.out.println(obj);
}2、Properties
Properties: Hashtable的子类,是一个可以和IO流相结合使用的集合类。
1. 实例变量及构造方法
protected Properties defaults ---------------------->一个属性列表,包含属性列表中所有未找到值的键的默认值。
public Properties()---------------------------------->创建一个无默认值的空属性列表。
public Properties(Properties defaults)----------->创建一个带有指定默认值的空属性列表。
2. 常用方法
public Object setProperty(String key,String value)-----------> 添加元素
public String getProperty(String key)---------------------------> 获取元素
public Set<String> stringPropertyNames() ---------------------> 获取所有的键的集合
Properties prop = new Properties();// 创建集合对象

prop.put("it01", "hello");   // 添加元素   继承Hashtable的方法
prop.setProperty("张三", "30");

Set<Object> set = prop.keySet();    // 遍历集合继承Hashtable的方法
for (Object key : set) {
        Object value = prop.get(key);
        System.out.println(key + "---" + value);
}

Set<String> set = prop.stringPropertyNames();
        for (String key : set) {
                String value = prop.getProperty(key);
                System.out.println(key + "---" + value);
}public void load(Reader reader)-----------------------------> 把文件中的数据读取到集合中
public void store(Writer writer,String comments)----------> 把集合中的数据存储到文件
Properties prop = new Properties();// 创建集合对象

prop.setProperty("ubuntu", "16.4");
prop.setProperty("redhat", "12");
prop.setProperty("centos", "5.0");

Writer w = new FileWriter("os.txt");
prop.store(w, "helloworld");//把集合中的数据存储到文件
w.close();

Reader r = new FileReader("os.txt");
prop.load(r);
r.close();
System.out.println("prop:" + prop);读写配置文件:
public static void main(String[] args) throws IOException {
        // 把文件中的数据加载到集合中
        Properties prop = new Properties();
        Reader r = new FileReader("user.txt");
        prop.load(r);
        r.close();

        // 遍历集合,获取得到每一个键
        Set<String> set = prop.stringPropertyNames();
        for (String key : set) {
                // 判断键是否有为"lisi"的,如果有就修改其值为"100"
                if ("lisi".equals(key)) {
                        prop.setProperty(key, "100");
                        break;
                }
        }

        // 把集合中的数据重新存储到文件中
        Writer w = new FileWriter("user.txt");
        prop.store(w, null);
        w.close();
}
页: [1]
查看完整版本: Java-029 IO流之序列化与Properties