“This is the 13th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

The vast sea of thousands of thousands, thank you for this second you see here. Hope my article is helpful to you!

Wish you in the future, keep love, go to the mountains and seas!

Senior stream I/O

Yesterday we learned about print streams in advanced streams, and in the larger system of IO streams, there are some advanced streams waiting to be unlocked.

So without further discussion, today we’re going to look at one of these advanced streams — serialization.

serialization

In the byte stream above, didn’t we see two streams: ObjectOutputStream and ObjectInputStream? This stream is mainly used in object serialization. Let’s look at serialization:

So, like the previous operations were all about the file and just write directly, so we’re learning object oriented, so can we save the object to the file and save it. The next serialization stream to learn is that you can transfer object data stored in memory into binary data stream. Any object can be serialized.

Java provides a mechanism for object serialization. An object can be represented by a sequence of bytes containing information such as the data of the object, the type of the object, and the properties stored in the object. After a sequence of bytes is written to a file, it is equivalent to persisting information about an object in the file. One thing to note is that you may not be able to read this file. This file is not meant for us to read, it’s meant to hold information about the object. We can then read that sequence of bytes back from the file, refactor the object, and deserialize it. The data of the object, the type of the object, and the property information stored in the object can all be used to create an object in memory.

Serialize the ObjectOutputStream

Objects are streamed to text files or transferred over a network. Implement persistent storage of objects.

1. Construction method

  • ObjectOutputStream public ObjectOutputStream(OutputStream out) : creates a serialized ObjectOutputStream with the specified byte OutputStream OutputStream. The argument passed in is an OutputStream byte OutputStream.

    Demonstration of construction method:

    public class ObjectStreamDemo {
        public static void main(String[] args) throws IOException {
            //public ObjectOutputStream(OutputStream out)
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\demo\\oos.txt")); }}Copy the code

2. Serialize operations

How do we serialize objects?

To serialize an object, we must not create an object first:

public class Person {
    private String name;
    private int age;

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

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge(a) {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }

    public String toString(a) {
        return "Person{name = " + name + ", age = " + age + "}"; }}Copy the code

You also need to know a method how to write the serialization method, right:

public final void writeObject(Object obj): Writes out the specified object.Copy the code

For an object to be serialized, the following conditions must be met:

  1. This object class must implement the Java.io.Serializable interface.Serializable can be seen to have no methods in it. A NotSerializableException is thrown.

    Here’s a look at what happens if you don’t:

    public class ObjectStreamDemo {
        public static void main(String[] args) throws IOException {
            //public ObjectOutputStream(OutputStream out)
            // Create the serialized stream object
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\demo\\oos.txt"));
    
            // Create an object
            Person p = new Person("Test robot One.".01);
    
            //public final void writeObject(Object obj)
            // Write out the object
            oos.writeObject(p);
    
            // Release resourcesoos.close(); }}Copy the code

    The object does not implement the Serializable interface, so after the program runs:

    Exception in thread "main" java.io.NotSerializableException: com.it.test11.Person
    	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    	at com.it.test11.ObjectStreamDemo.main(ObjectStreamDemo.java:18)
    Copy the code

    Indicates that you have not implemented the Serializable interface. So let’s implement this interface now

    public class Person implements Serializable {... }Copy the code

    Now let’s look at the file information:

    This is… Can you read it? It’s okay if you can’t read it, but if you can read it, we can read it. So let’s see how do we read?

Deserialize the ObjectInputStream

To restore stream object data in a text file or network to objects.

1. Construction method

  • Public ObjectInputStream(InputStream in) : creates an ObjectInputStream that deserializes InputStream with the specified byte InputStream. The argument passed in is an InputStream byte InputStream.

    The constructor is shown below:

    public class ObjectStreamDemo2 {
        public static void main(String[] args) throws IOException {
            //public ObjectInputStream(InputStream in)
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\demo\\oos.txt")); }}Copy the code

2. Deserialization operation

Now that we’ve serialized objects into files, how do we deserialize file information into objects?

So first we need to know what method to read:

public final Object readObject (a): Reads an object.Copy the code

Can we do the same thing we did when we read files? Let’s try it out. To put it bluntly, if you don’t, try first, and in the process of trying, keep correcting your mistakes, so that you can get better.

public class ObjectStreamDemo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //public ObjectInputStream(InputStream in)
       // Create the deserialized object
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\demo\\oos.txt"));

        // Restore the object
        Object obj = ois.readObject();

        // Release resources
        ois.close();

        // Output objectsSystem.out.println(obj); }} Program execution result: Person{name = test robot1Number, age =1}
Copy the code

3. Possible problems during deserialization

Now that we’ve serialized the object into the file, it’s ok for us to read it the first time, right, but if I modify the Person class again. And then when I read, what happens?

public class Person implements Serializable {
    private String name;
    private int age;
    private String address;// Add a new attribute. }Copy the code

Read the result again:

Exception in thread "main" java.io.InvalidClassException: com.it.test11.Person; local class incompatible: stream classdesc serialVersionUID = 1228968110604265735, local class serialVersionUID = 3463310223685915264
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1829)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1713)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1986)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at com.it.test11.ObjectStreamDemo2.main(ObjectStreamDemo2.java:14)
Copy the code

You can see a bunch of red exceptions on your console. An InvalidClassException has occurred. Why does this happen? Specific reasons may be as follows:

  • The sequence version number of the class does not match the version number of the class descriptor read from the stream
  • This class contains unknown data types
  • This class has no accessible parameterless constructor

Let’s look at the specific reasons for the exception:

com.it.test11.Person; local class incompatible: stream classdesc serialVersionUID = 1228968110604265735, local class serialVersionUID = 3463310223685915264
Copy the code

You can see that the modifications we made to the Person class have caused the version numbers of the sequence to be inconsistent. Because our modified serial number is not saved in the file again, the latest serial number is inconsistent with the file serial number, resulting in an exception. So how do we solve this problem? There are two ways:

  1. Write to the file again: After we modify the Person class, we write to the file again, and you can see that after reading it again, there is no problem. This method is more troublesome, each time the modification has to be rewritten to the file, to read again, is not relatively troublesome, the next to teach you a method once and for all.

  2. Write a fixed version number: Since each change causes the sequence version number of the file to change, we can solve this problem by setting a fixed serialization version number. So how do you set it up?

    // Add the sequence version number
    private static final long serialVersionUID = 2071565876962023344L; 
    Copy the code

    Just put this in the first line of the Person class, and we’ll write again, and we’ll have no problem reading.

Transient keyword

A class might have a lot of member variables, but what if I don’t want to serialize some of them?

You just need to add a keyword transient before the variable name.

  • It’s transient. Indicates that the variable does not want to be serialized.

    Now in the Person class, I just want to keep the name variable, the age variable, and I don’t want it to be serialized.

    private transient int age;
    Copy the code

    Now after we rewrite and read:

    Person{name = Test robot1Number, age =0}
    Copy the code

    As you can see, the age is not serialized to the file.

Set serialization cases

Example: Serialize a collection containing multiple custom teacher objects into an arrayList.txt file. Deserialize arrayList.txt and iterate over the collection, printing the object information.

How do we implement this case:

  1. Create several teacher objects and save them to the collection.
  2. Serialize the collection.
  3. When you deserialize a read, you only need to read it once and convert it to a collection type.
  4. Iterating through the collection, all teacher information can be printed.

OK, now that you know the process, let’s do it directly:

Create the Teacher class and implement the Serializable interface.

package com.it.test12;

import java.io.Serializable;

public class Teacher implements Serializable {
    private String name;
    private int age;


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

    public String getName(a) {
        return name;
    }

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

    public int getAge(a) {
        return age;
    }

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

    public String toString(a) {
        return "Teacher{name = " + name + ", age = " + age + "}"; }}Copy the code

The serialization operation is being tested.

package com.it.test12;

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

public class ObjectStreamTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // Create the teacher object
        Teacher t1 = new Teacher("Miss Wang".40);
        Teacher t2 = new Teacher("Miss Li".48);
        Teacher t3 = new Teacher("Mr. Zhang".46);

        // Add to the collection.
        ArrayList<Teacher> arrayList = new ArrayList<>();
        arrayList.add(t1);
        arrayList.add(t2);
        arrayList.add(t3);

        // Serialize the operation
        serializ(arrayList);

        // Do the serialization first, and then comment out the serialization. Then the deserialization is performed
// serializRead();
    }

     // Deserialization operation
    private static void serializRead(a) throws IOException, ClassNotFoundException {
        ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("list.txt"));
        // Read the object and forcibly convert it to ArrayList
        ArrayList<Teacher> list  = (ArrayList<Teacher>)ois.readObject();

        for (int i = 0; i < list.size(); i++ ){
            Teacher s = list.get(i);
            System.out.println(s.getName()+"--"+ s.getAge()); }}// Serialize the operation
    private static void serializ(ArrayList<Teacher> arrayList) throws IOException {
        // Create the serialization stream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));
        // Write the object
        oos.writeObject(arrayList);
        // Release resourcesoos.close(); }}Copy the code

After running the program:

Teacher wang,40Miss li,48Teacher zhang,46
Copy the code

conclusion

I believe you have a good understanding of the serialization of advanced streams in IO streams. Look forward to the next chapter of advanced streams — streams that manipulate basic data.

Of course, there are many streams waiting to watch together next time! Welcome to the next chapter!

So far, the world is closed for today, good night! Although this article is over, BUT I still, never finished. I will try to keep writing articles. The coming days are long, and the horse is slow!

Thank you for seeing this! May you be young and have no regrets!

Note: If there are any mistakes and suggestions, please leave a message! If this article is also helpful to you, I hope you give a lovely and kind attention, thank you very much!