将Java中的内容直接存储为二进制文件

目前有这个需求,需要将java跑好的结果持久化,但是如果一个个输出为文本文件又不太好办,因为里面东西太多太杂,所以最好的办法是直接输出为二进制文件,把数据连同存储数据的类一起存进去,就行python中的pickle类所做的一样。

在网上转了一圈,大部分是讲如何输出为文本文件的,所以在经过查询和调试以后,给出我自己的方法。

要实现这个功能主要有两点,一是FileOutputStream和ObjectOutputStream的搭配使用,一是Serializable接口的实现。

1.FileOutputStream和ObjectOutputStream的搭配使用

File file = new File(".\\test.dat") ; // 建立文件
try{
    TestClass tc = new TestClass(5,"akldsj") ;
    if (!file.exists()) file.createNewFile() ;
    FileOutputStream fos = new FileOutputStream(file) ;
    ObjectOutputStream oos = new ObjectOutputStream(fos) ;
    oos.writeObject(tc);
    System.out.println("文件已存入");
    oos.close();
    fos.close();
}catch (IOException e){
    e.printStackTrace();
}

其中TestClass对象tc就是我们要存入的内容。
同理,如果要取出来,则需要FileInputStream和ObjectInputStream的配合

try{
    FileInputStream fis = new FileInputStream(file) ;
    ObjectInputStream ois = new ObjectInputStream(fis) ;
    TestClass tc = (TestClass)ois.readObject() ;
    System.out.println(tc);
    ois.close();
    fis.close();
}catch (IOException e){
    e.printStackTrace();
}catch (ClassNotFoundException e){
    e.printStackTrace();
}

2.Serializable接口的实现

对于自定义类,如果直接使用上述代码是会报错的,所以需要自己定义的类实现Serializable接口,否则会报java.io.NotSerializableException错误

跑去这个接口的定义里发现似乎并没有要自己实现的方法。但是这边要注意有一个很容易忽略的地方,就是serialVersionUID

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

serialVersionUID有两种显示的生成方式:
一个是默认的1L,比如:
private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
private static final long serialVersionUID = xxxxL;

这边采用前一种方法。

class TestClass implements  Serializable{
    private static final long serialVersionUID = 1L ;
    private int a ;
    private String b ;
    TestClass(int a, String b){
        this.a = a ;
        this.b = b ;
    }
    public String toString(){
        return String.valueOf(a) + b ;
    }
}

最后得到程序的运行结果是

文件已存入
5akldsj

可以看到文件存入后又读出成功,且可以直接使用

你可能感兴趣的:(java)