大数据预科班18

大数据预科班18

序列化与反序列化流

  • 将一个对象进行完整保存的过程--序列化--持久化
  • 序列化是持久化的一种方式
  • 反序列化--将对象完整还原回来

1. 准备要序列化的对象
    1. Person p=new Person();
    2. p.setAge(12);
    3. p.setName("asdfdf");
2. 创建用于序列化的流
    1. ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("E:\\p.data"));
3. 将对象序列化
    1. oos.writeObject(p);
4. 关流
    1. oos.close();
  • 注意事项--类实现序列化接口,标记该类的对象可以序列化
  • Serializable--没有属性和方法,只是标记类可以被序列化
  • 静态属性用static修饰,那么该属性不会被序列化出去--没有必要序列化出去(类加载的时候static就存在了)
  • 反序列化

1. 创建反序列化流
    1. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E'\\\p.data"));
2. 反序列化对象
    1. Person p =(Person)ois.readObject();
3. 关流
    1. ois.close();
  • transient不允许序列化;transient不序列化;
  • 如果一个属性没有被序列化出去,反序列化时给个默认值
  • 先序列化,再改源码,现在反序列化--InvalidClassException---解决---private static final long serialVersionUID=321L;
  • 版本号:serialVersionUID,当一个对象反序列化回来的时候,会自动的比较版本号和当前类中的版本号是否一致,同一个,才允许反序列化;如果没有手动提供,它会自己根据当前环境进行创建。
  • 集合--大多数不能被序列化--地址(没有意义)--底层大多用transient修饰
  • 安全问题:加锁--放在盒子里----锁----钥匙

package com.peng.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;

/**
 * @author kungfu~peng
 * @data 2017年9月26日
 * @description 加密--盒子
 */
public class JiaMi {
    // 钥匙
    private static Key key;

    public static void main(String[] args) throws Exception {
        Person p = new Person(1, "qq");
        JiaMi.setClock(p, new FileOutputStream("E:\\a.data"));
        System.out.println(JiaMi.getClock(new FileInputStream("E:\\a.data")));
    }

    // 加密
    public static <E> void setClock(E e, FileOutputStream fs) throws Exception {
        // 创建钥匙的生产者
        KeyGenerator kg = KeyGenerator.getInstance("DESede");
        // 生产钥匙
        key = kg.generateKey();
        // 生产锁
        Cipher cipher = Cipher.getInstance("DESede");
        // 锁和钥匙进行匹配
        cipher.init(Cipher.ENCRYPT_MODE, key);
        // 创建盒子
        SealedObject sealObj = new SealedObject((Serializable) e, cipher);
        // 创建序列化输出流
        ObjectOutputStream oos = new ObjectOutputStream(fs);
        // 将盒子序列化--持久化
        oos.writeObject(sealObj);
        // 关闭流
        oos.close();
    }

    // 解密
    public static <E> E getClock(FileInputStream fin) throws Exception {
        // 创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(fin);
        // 读取盒子对象
        SealedObject sealObj = (SealedObject) ois.readObject();
        // 解封对象

        return (E) sealObj.getObject(key);
    }

}

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private int age;
    private String name;

    public Person() {
        super();
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

}

Properties

  • 本身是一个映射
  • 不属于流
  • HashTable的子类
  • 可以持久化的映射
  • 键值对都是String,而且只能是String

1. 创建properties对象
    1. Properties  prop= new Properties();
2. 添加 键值对
    1. prop.setProperties();
3. 持久化这个映射--必须存储到properties文件中(文件名,注释--解释当前properties文件的作用)
    1. prop.store(new FileOutputStream("a.properties"),"comments");
4. 反序列化文件
    1. prop.load(new FileInputStream("a.properties"));
    2. 输出prop.getProperty(key);
    3. 如果键不存在,返回null
    4. getProperty(key,default);// 给个默认值
5. 序列化时必须存储到properties文件中--iso-8859-1编码--输入中文时转化为对应的编码

枚举

1. 以前:类--构造函数私有化+static+final
2. 枚举类enum-----------类的一切都满足
    enum Level{
        //默认构造函数是私有的
        //每个枚举量用,隔开,最后结束;
        //枚举类常量必须定义在首行
        A,B,C,D,E;
    }

    enum Level{
        //默认构造函数是私有的
        //每个枚举量用,隔开,最后结束;
        //枚举类常量必须定义在首行
        A(1),B(2),C(3),D(4),E(5);

        private Level(int i){

        }
    }       
3.   允许抽象方法的定义但类名上不加abstract
  • 在取值相对固定且能够一 一列举的情况下,建议使用枚举
  • enum来定义一个枚举类,常量放首行
  • enum的顶级父类
  • jdk1.5特性之一
  • 构造函数只能为private的
  • enum的使用与普通类基本类似
  • jdk1.5--switch-case可以用enum

//Properties
package com.peng.demo;

import java.util.Properties;
import java.util.Set;

/**
 * @author kungfu~peng
 * @data 2017年9月26日
 * @description properties
 */
public class JiaMi {
    public static void main(String[] args) {
        Properties pps = new Properties();
        pps.setProperty("a", "1");
        pps.setProperty("b", "2");
        pps.setProperty("c", "3");
        pps.setProperty("d", "4");
        pps.setProperty("e", "5");
        for (String name : pps.stringPropertyNames()) {
            System.out.println(pps.getProperty(name));
        }
    }

}

//Properties与流操作
package com.peng.demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

/**
 * @author kungfu~peng
 * @data 2017年9月26日
 * @description properties
 */
public class JiaMi {
    public static void main(String[] args) throws FileNotFoundException,
            IOException {
        // Properties对象--存
        Properties pps = new Properties();
        pps.setProperty("a", "1");
        pps.setProperty("b", "2");
        pps.setProperty("c", "3");
        pps.setProperty("d", "4");
        pps.setProperty("e", "5");
        pps.store(new FileOutputStream("E:\\pps.properties"), "add elements");
        // Properties对象--取
        Properties pps2 = new Properties();
        pps2.load(new FileInputStream("E:\\pps.properties"));
        for (String name : pps2.stringPropertyNames()) {
            System.out.println(pps.getProperty(name));
        }
        System.out.println();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值