Java 杂谈码农的世界程序员

2019-03-07

2019-03-07  本文已影响15人  DreamPath

序列化流,打印流基础知识整理

序列化流(对象流)

把对象以流的形式存储在硬盘上或者数据库中的过程就是写序列化流。
原理:

package obj_outputStream;

/**
 * public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream
 * 该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任 何状态序列化或反序列化,会抛出 NotSerializableException 。 
 * 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,
 * 则该属性必须注明是瞬态的,使用 transient 关键字修饰。
 */
public class Employee implements java.io.Serializable{
    public String name;
    public String address;
    public transient int age;// transient瞬态修饰成员,不会被序列化

    public void checkAddress(){
        System.out.println("Address check:"+name+"---"+address);
    }

}

2.写出对象方法

package obj_outputStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * public final void writeObject (Object obj) : 将指定的对象写出
 */
public class Serializable_obj {
    public static void main(String[] args) {

        Employee e = new Employee();
        e.name="周星驰";
        e.address="香港";
        e.age=65;

        try {
            FileOutputStream fileOut=new FileOutputStream("D:\\Java代码\\Java基础加强\\sjs.txt");
            ObjectOutputStream obj=new ObjectOutputStream(fileOut);

            obj.writeObject(e);
                obj.close();
                fileOut.close();
            System.out.println("Serialized data is save!");// 姓名,地址被序列化,年龄没有被序列化。
        } catch (IOException e1) {
            e1.printStackTrace();
        }//Serialized data is save!


    }

}

对象输入流:
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

package obj_outputStream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 *   public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream
 *  如果能找到一个对象的class文件,我们可以进行反序列化操作,调用
 *  ObjectInputStream 读取对象的方法:
 *  public final Object readObject () : 读取一个对象
 *  
 *  注意:
 *  对于JVM可以反序列化对象,它必须是能够找到class文件的类。
 *  如果找不到该类的class文件,则抛出一个 ClassNotFoundException 异常。 
 */
public class InputStreamDemo {
    public static void main(String[] args) {
        Employee e=null;

        try {
            FileInputStream in=new FileInputStream("D:\\Java代码\\Java基础加强\\sjs.txt");
            ObjectInputStream inputStream=new ObjectInputStream(in);

           e=(Employee)inputStream.readObject();

                inputStream.close();
                in.close();

        } catch (IOException | ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        System.out.println("Name:"+e.name);
        System.out.println("Address:"+e.address);
        System.out.println("Age:"+e.age);
        /**输出结果:
         * Name:周星驰
         * Address:香港
         * Age:0     (年龄未被序列化存储,默认为0)
         */
    }
}
反序列化操作2

当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个 InvalidClassException 异常。发生这个异常的原因如下:

package obj_outputStream;

/** 
 * public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream
 */
public class Employee implements java.io.Serializable{
  
    // 序列化2
    private static final long serialVersionUID=1l;
    public String name;
    public String address;
    public int eit;
    public void checkAddress(){
        System.out.println("Address check:"+name+"---"+address);
    }
}
序列化集合

1.将存有多个自定义对象的集合序列化操作,保存到 list.txt 文件中。

  1. 反序列化 list.txt ,并遍历集合,打印对象信息。

创建学生类

package obj_outputStream;

import java.io.Serializable;

/**
 * 1. 把若干学生对象 ,保存到集合中。
 * 2. 把集合序列化。
 * 3. 反序列化读取时,只需要读取一次,转换为集合类型。
 * 4. 遍历集合,可以打印所有的学生信息
 */
public class Student implements Serializable {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

测试类

package obj_outputStream;

import java.io.*;
import java.util.ArrayList;

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

        Student student = new Student("李小龙", 22);
        Student student1 = new Student("王五", 42);
        Student student2 = new Student("叶问", 52);
        Student student3 = new Student("霍元甲", 32);

        ArrayList<Student> students = new ArrayList<>();
        students.add(student);
        students.add(student1);
        students.add(student2);
        students.add(student3);
        // 序列化操作
        serializ(students);
        //反序列化操作
        ObjectInputStream stream = new ObjectInputStream(new FileInputStream("aaa.txt"));
        // 读取对象,强转为ArrayList类型
        ArrayList<Student> list = (ArrayList<Student>) stream.readObject();
        for (int i = 0; i < list.size(); i++) {
            Student s = list.get(i);

            System.out.println("姓名:" + s.getName() + "----" + "年龄" + s.getAge());
        }
        stream.close();

    }
        //传递存储对象的集合
    private static void serializ(ArrayList<Student> students) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("aaa.txt"));
        out.writeObject(students);
        out.close();


    }
}

打印流

只做输出没有输入
分为字节打印流和字符打印流
PrintWriter:字符打印流
特点:

package obj_outputStream;

import java.io.IOException;
import java.io.PrintStream;

/**
 * public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流
 * PrintStream ps = new PrintStream("ps.txt")
 */
public class printStreamDemo {
     public static void main(String[] args) throws IOException {
         // 调用系统的打印流,控制台直接输出97                  
          System.out.println(97);
          // 创建打印流,指定文件的名称                  
         PrintStream ps = new PrintStream("ps.txt");
         // 设置系统的打印流流向,输出到ps.txt            
          System.setOut(ps);
          // 调用系统的打印流,ps.txt中输出97           
         System.out.println(97); }
    }
}
上一篇下一篇

猜你喜欢

热点阅读