美文网首页
Java中序列化和打印流

Java中序列化和打印流

作者: 丛鹏 | 来源:发表于2020-06-16 10:38 被阅读0次

    一、对象序列化和反序列化

    1、概述

    对象的序列化:对象中的数据,以流的形式,写入到文件中并保存的过程称为写出对象,即对象的序列化

    对象的反序列化:在文件中,以流的形式,将对象读出来的过程称为读取对象,即对象的反序列化

    ObjectOutputStream 写对象,实现序列化

    ObjectInputStream 读取对象,实现反序列化

    2、对象序列化ObjectOutputStream和反序列化ObjectInputStream

    ObjectOutStream 将 Java 对象的基本数据类型和图形写入 OutputStream,可以使用ObjectOutStream 读取(重构)对象,通过在流中使用文件可以实现对象的持久存储

    ObjectInputStream 对上面使用的 ObjectOutputStream 写入的基本数据和对象进行反序列化

    void writeObject(Object obj):写出对象的方法

    Object readObject():读取对象方法

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        writeObject();      //写对象,实现序列化

        readObject();      //读取对象,实现反序列化

    }

    private static void writeObject() throws IOException {

        //创建字节输出流,封装文件

        FileOutputStream FOS = new FileOutputStream("F:\\TestPath\\FileOutputStream.txt");

        //创建写出对象的序列化流的对象,构造方法传递字节输出流

        ObjectOutputStream OOS = new ObjectOutputStream(FOS);

        Person P1 = new Person("Tom",18);

        //调用序列化流的方法writeObject,写出对象

        OOS.writeObject(P1);

        OOS.close();

    }

    private static void readObject() throws IOException, ClassNotFoundException {

        FileInputStream FOS = new FileInputStream("F:\\TestPath\\FileOutputStream.txt");

        //创建反序列化流,构造方法中,传递字节输入流

        ObjectInputStream OIS = new ObjectInputStream(FOS);

        //调用反序列化流的方法 readObject()读取对象

        Object obj = OIS.readObject();

        System.out.println(obj);

        OIS.close();

    }

    二、序列化注意事项

    1、静态不能序列化

    序列化是把对象数据进行持久化存储

    静态的东西不属于对象,而属于类

    2、瞬态 transient 关键字

    当一个类的对象需要被序列化时,某些属性不需要被序列化,这时不需要序列化的属性可以使用关键字transient

    被transient修饰的属性不会被序列化

    transient关键字只能修饰成员变量

    3、Serializable 接口的含义

    给需要序列化的类加上标记,该标记中没有任何抽象方法(如上面的Person类)

    只有实现 Serializable 接口的类的对象才能被序列化

    4、序列化中的序列号冲突问题

    产生冲突原因:当一个类实现 Serializable 接口后,创建对象并将对象写入文件,之后更改了源代码,再次从文件中读取对象时会报异常

    产生冲突分析:在编译的时候,会根据类的定义,给class文件中计算一个序列号,当序列化和反序列化(写和读)时,除了将类中的数据进行读写,会连同序列号一起读写,而当改动源码,需要重新编译,序列号也就发生变化,此时如果不进行写对象,而是直接读,此时就会出现序列号冲突的异常

    解决方法:自定义序列号 private static final long serialVersionUID = 1478652478456L;  serialVersionUID 就是序列号,自定义序列号采用static final修饰,不予许修改,所以当程序源码发生变化时,序列号也不会发生变化。将这条语句复制到实现 Serializable 接口的类中任何无语法错误的位置即可,等号右边的可变

    三、打印流

    打印流作为添加输出数据的功能,使它们能够方便的打印地打印各种数据值表示形式。打印流根据流的分类可分为:字节打印流==>PrintStream 和 字符打印流==>PrintWriter

    1、打印流特点

    打印流不负责数据源,只负责数据目的

    为其他输出流添加功能

    永远不会抛出 IOException,但可能抛出别的异常

    两个打印流的方法完全一致

    构造方法就是打印流的输出目的端

    PrintStream构造方法:接收 File 类型,接收字符串文件名,接收字节流 OutputStream

    PrintWriter构造方法:接收字符串文件名,接收字节输出流 OutputStream ,接收字符输出流 Writer

    2、打印流常用的方法

    void print(String str):输出任意类型的数据

    void println(String str):输出任意类型的数据,自动写入换行操作

    public static void main(String[] args) throws IOException {

        FilePrintWriter();      //打印流输出目的是File对象

        FileOutputStreamPrintWriter();      //打印流输出目的是字节流对象

        FileWriterPrintWriter();        //打印流输出目的是字符流对象

        StringPrintWriter();        //打印流输出目的是String文件名

    }

    private static void FilePrintWriter() throws FileNotFoundException {

        File F = new File("F:\\TestPath\\FilePrintWriter.txt");

        PrintWriter PW = new PrintWriter(F);

        PW.println(100);    //原样输出

        PW.write(100);      //按ASCII表输出

        PW.close();

    }

    private static void FileOutputStreamPrintWriter() throws FileNotFoundException {

        FileOutputStream FOS = new FileOutputStream("F:\\TestPath\\FileOutputStreamPrintWriter.txt");

        PrintWriter PW = new PrintWriter(FOS);

        PW.println(123);

        PW.close();

    }

    private static void FileWriterPrintWriter() throws IOException {

        FileWriter FW = new FileWriter("F:\\TestPath\\FileWriterPrintWriter.txt");

        PrintWriter PW = new PrintWriter(FW);

        PW.println("lkjklj");

        PW.close();

    }

    private static void StringPrintWriter() throws FileNotFoundException {

        PrintWriter PW = new PrintWriter("F:\\TestPath\\StringPrintWriter.txt");

        PW.println(888);

        PW.close();

    }

    3、打印流开启自动刷新

    输出的数据目的必须是流对象(OutputStream或Writer)

    必须调用 println、printf、format 三个方法中的一个

    public PrintWriter(OutputStream out, boolean autoFlush)

    public PrintWriter(Writer out, boolean autoFlush)

    private static void fun() throws IOException {

        FileWriter FW = new FileWriter("F:\\TestPath\\FilePrintWriter.txt");

        PrintWriter PW = new PrintWriter(FW,true);

        for(int i = 0;i < 5;i++)

        {

            PW.println("hello");

        }

        PW.close();

    }

    4、打印流复制文本文件

    使用 BufferedReader+File 读取文本行

    使用 PrintWriter+println 自动刷新

    public static void main(String[] args) throws IOException {

        FileReader fr = new FileReader("F:\\TestPath\\FilePrintWriter.txt");

        BufferedReader br = new BufferedReader(fr);

        FileWriter fw = new FileWriter("D:\\a.txt",true);

        PrintWriter pw = new PrintWriter(fw);

        String line;

        while ((line = br.readLine()) != null)

        {

            pw.println(line);

        }

        pw.close();

    }

    相关文章

      网友评论

          本文标题:Java中序列化和打印流

          本文链接:https://www.haomeiwen.com/subject/ajritktx.html