I/O流

I/O流:主要操作文件内容,结合前面所学的File类,我们可以读取和写出文件,也可以修改文件的字符集编码…

处理流:

处理流就相当于外衣,每件衣服的作用不同,每个处理流的作用也不同,处理流可以实现多嵌套,即可以有多个处理流,每个处理流的功能不同!

前面已经学习过了5个处理流了,现在你对I/O的操作是不是已经烂熟于心了,今天我们将要学习的对象流,重点学习对象的序列化机制!!!

学习大纲:

Java中p处理 java中的处理流有哪些_开发语言

1.缓冲流

2.转化流

3.输出、输出流

4.打印流

5.数据流

6.对象流

对象流和数据流类似,唯一的不同是对象流能读取/写出对象,对象流能对基本数据类型+String类型数据进行读取/写出的操作,能对保存的数据进行持久化保存到文件的操作;

对象流的强大之处,就是能把Java中的对象写入到数据源中,也能把对象从数据源中还原回来!!!

序列化:将Java对象添加到数据源中;
标准:用ObjectOutputStream保存基本数据类型或者对象的机制;

反序列化:将Java对象从数据源中还原回来。
标准:用ObjectInputStream读取基本数据类型或者对象的机制。

我们这里可以通俗的把数据源理解成一个哆啦A梦的转换机,可以实现大熊在任意时空中的穿梭,并保证了大熊的完整性,不会因为过程而发生变形/损失;
Java层面的理解就是:数据在序列化和反序列化的过程中,保证对象唯一对应,并不会因为序列化的问题而在反序列化的过程中丢失。

对象的序列化机制

允许把内存中的Java对象转换成和平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点(序列化);其它程序获取了这种二进制流,就可以恢复成原来的Java对象(反序列化)。

序列化的好处:

可以将传入的任何实现了Serializable接口的对象转换为字节数据,使其在保存和还原的过程中可被还原!!!

序列化就是JavaEE平台的基础;RMI(Remote Method Invoke – 远程方法调用)过程的参数和返回值都必须实现的机制。

序列化图解过程:

Java中p处理 java中的处理流有哪些_java-ee_02

展开说明:
interface Serializable
它里面是没有方法或者参数的,就相当于一个序列化机制的标识

public static final long serialVersionUID = xxxxxL;(自定义值)
serialVersionUID用来表明类的不同版本间的兼容性。
简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
注意事项

1.序列化的对象必须实现Serializable接口;

2.序列化的对象必须定义全局常量serialVersionUID;

3.序列化的对象中的所有属性必须全部实现序列化…

针对第三条,就是为了预防对象中,包含其他自定类对象,但自定义类并没有实现序列化机制(也就是没有满足第1、2条);

4.不能序列化static和transient修饰的变量!!!

static所属于类,并不属于对象;
transient相当于临时变量。
基本数据类型底层都已经实现了Serializable接口,和定义了全局常量serialVersionUID,所以我们在使用的时候不需要重新定义…

Java中p处理 java中的处理流有哪些_Java中p处理_03

//对第三条的解释
public class Person implements Serializable {

    public static final long serialVersionUID = 415539532L;
    String name;
    int age;
    int id;
    Smile smile;
}
public class Smile implements Serializable{

    public static final long serialVersionUID = 4155569532L;
    boolean start;
}
对象流案例:
自定义对象:
public class Person implements Serializable {

    public static final long serialVersionUID = 415539532L;
    String name;
    int age;
    int id;
    Smile smile;


    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                ", smile=" + smile +
                '}';
    }


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

    public Person(String name, int age, int id, Smile smile) {
        this.name = name;
        this.age = age;
        this.id = id;
        this.smile = smile;
    }

    public Person() {
    }

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

}
写入/读取对象:
/**
     * 练习
     */
    public static void objectStreamTest(String path){

        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream(path));
            ois = new ObjectInputStream(new FileInputStream(path));

           oos.writeObject(new Person("小红",28));
            oos.flush();

            Person person = (Person) ois.readObject();
            System.out.println(person);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    
    //Person{name='小红', age=28, id=0, smile=null}