内置serialize序列化
创建一个自定义类:
class VarClass1 implements Serializable { boolean aBoolean; char aChar; byte aByte; short aShort; int anInt; long aLong; float aFloat; double aDouble; String aString; transient boolean tBoolean; transient char tChar; transient byte tByte; transient short tShort; transient int tnInt; transient long tLong; transient float tFloat; transient double tDouble; transient String tString; }
序列化到文件:
VarClass1 vc1 = new VarClass1(); // 设置属性值 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serialize.bin")); oos.writeObject(vc1); oos.flush(); oos.close();
序列化后,类中所有的不被transient关键字修饰的属性都会以二进制形式存储在文件中。
从文件中读取(反序列化):
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serialize.bin")); VarClass1 vc1 = (VarClass1) ois.readObject(); // 强制转换 ois.close();
从文件中读取类时,除了可能会抛出常见的IOException外,还可能会抛出以下异常:
- java.io.EOFException:文件为空,或者在文件末尾使用read操作
- java.io.StreamCorruptedException:文件内容不能被反序列化
- java.io.InvalidClassException:文件中的类和程序中的类,属性定义不一样
第三方Json序列化
找一个第三方的Json库,我用的是Google的Gson(开源在Github),将jar包添加到工程。
定义一个类。代码和前面的差不多,只是不需要实现Serializable接口。
序列化到文件:
VarClass1 vc1 = new VarClass1(); // 设置属性值 JsonWriter jw = new JsonWriter(new FileWriter("json.json")); (new Gson()).toJson(vc1, vc1.getClass(), jw); jw.flush(); jw.close();
序列化后,类中所有的不被transient关键字修饰的属性都会以json数据类型形式存储在文件中。默认无缩进。
缩进后:
从文件中读取(反序列化):
JsonReader jr = new JsonReader(new FileReader("json.json")); VarClass1 vc1 = (new Gson()).fromJson(jr, VarClass1.class); // 不需要强制转换 jr.close();
使用Gson反序列化时,需要注意以下几点:
- 出现Json文件语法出错等问题,程序会报com.google.gson.JsonSyntaxException
- 如果文件为空,或者说JsonReader流为空的话,那么Gson获取到的对象为null,而不是报异常
- 文件中的类和程序中的类,属性定义不一样(比如transient关键字不一致、不存在的属性、属性缺失等),那么Gson读取文件到类时会跳过错误(忽略transient、忽略不存在的属性、不存在的属性取默认值0&0.0&null等),而不会报异常
后记
- 内置的序列化只要出了点问题就会报异常,而Google的Gson则是尽量忽略问题。哪个更为符合自己的习惯,哪个更适合实际场景,就用哪个吧。至于优劣只能见仁见智了。
- 但是Json序列化之后的内容,可读性还是要大大优于内置序列化之后的内容,也更容易修改,毕竟后者是用二进制的。