大数据预科班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();
}
}