📜  JavaObjectInputStream和ObjectOutputStream的区别

📅  最后修改于: 2021-09-10 02:56:12             🧑  作者: Mango

在一个软件项目中,在很多情况下,都需要传输数据,可以使用Java IO包中的ObjectOutputStream和ObjectInputStream来处理。通常,数据以二进制格式写入,因此我们无法查看内容。序列化是将对象写入输出流的过程。我们可以编写一个类对象本身,它包含原始数据类型和Java对象图的组合。反序列化是从输入流重建对象的过程。

实现:让我们看看 ObjectOutputStream 我们为它创建了一个名为“VehicleSpecifications”的 POJO 类。

示例 1:

Java
// Java Program simply illustrtaing POJO / Model class
 
// Importing input output class
import java.io.Serializable;
 
// Class 1
// Implements Serializable  for POJO class to aavoid
// NotSerializableException will be thrown
public class VehicleSpecifications implements Serializable {
 
    // Member variables of this class
    private String color;
    private String type;
    private String name;
    private double price;
 
    // Constructors of this class
 
    // Constructor- 1
    // Default constructor
    public VehicleSpecifications() {}
 
    // Constructor- 2
    // Parameterized constructor accepting all attributes and
    // helps to create a VehicleSpecifications class
    public VehicleSpecifications(String color, String type,
                                 String name, double price)
    {
 
        // This keyword refers to current object itself
        this.color = color;
        this.type = type;
        this.name = name;
        this.price = price;
    }
 
    // Methods of this class
    // Specfically  Getter and Setter methods
 
    // Method 1
    public double getPrice() { return price; }
 
    // Method 2
    public void setPrice(double price)
    {
        this.price = price;
    }
 
    // Method 3
    public String getName() { return name; }
 
    // Method 4
    public void setName(String name) { this.name = name; }
 
    // Method 5
    public String getColor() { return color; }
 
    // Method 6
    public void setColor(final String color)
    {
        this.color = color;
    }
 
    // Method 7
    public String getType() { return type; }
 
    // Method 8
    public void setType(final String type)
    {
        this.type = type;
    }
}


Java
// Class 2
// Java Program to Create Few VehicleSpecifcation and
// Writing in a File
 
// Importing required classes from packages
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class VehicleSpecificationsSerializer {
 
    // main driver method
    public static void main(String[] args)
    {
 
        // Output file been passed in a string
        String sampleOutputFile = "VehicleSpecifcation.db";
 
        // Try block to check for exceptions
        try {
 
            // Create a objectoutputstream accepting the
            // file name as VehicleSpecifcation.db
            ObjectOutputStream vehicleObjectOutput
                = new ObjectOutputStream(
                    new FileOutputStream(sampleOutputFile));
 
            // Create a list of VehicleSpecifications class
            List listSpecifications
                = new ArrayList();
 
            // Add the necessary data using standard add()
            // method Custom input
            listSpecifications.add(
                new VehicleSpecifications("Radiant Red",
                                          "SUV", "WR-V",
                                          1700000f));
 
            listSpecifications.add(
                new VehicleSpecifications("Metallic Blue",
                                          "SUV", "WR-V",
                                          1800000f));
 
            listSpecifications.add(
                new VehicleSpecifications(
                    "Black", "SUV", "WR-V", 1900000f));
 
            // We are writing the whole object into the file
            // which is a list item of VehicleSpecifications
            // object
            vehicleObjectOutput.writeObject(
                listSpecifications);
 
            // Closing the connection to release memory
            vehicleObjectOutput.close();
        }
 
        // Catch block to handle the exceptions
        catch (IOException ex) {
 
            // Print the exceptions along with line number
            // using printStackTrace() method
            ex.printStackTrace();
        }
    }
}


Java
// Java Program to make above code human-readable
 
// Importing classes from required packages
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class VehicleSpecificationsDeSerializer {
 
    // main driver method
    public static void main(String[] args)
    {
 
        // Input file
        String sampleInputFile = "VehicleSpecifcation.db";
 
        // Try block to check for exceptions
        try {
 
            // Creating an object of ObjectInputStream class
            ObjectInputStream vehicleObjectInputStream
                = new ObjectInputStream(
                    new FileInputStream(sampleInputFile));
 
            // Creating a List class object
            // Declaring object of user defined type
            // (VehicleSpecifications)
            List
                vehicleSpecificationsListData
                = new ArrayList();
 
            // Using readObject, bringing back the whole
            // list item of VehicleSpecifications into scope
 
            // readObject which can read class attributes
            // using read methods provided by
            // ObjectInputStream.
            vehicleSpecificationsListData
                = (ArrayList)
                      vehicleObjectInputStream.readObject();
 
            // Iterating over above object created
            for (int i = 0;
                 i < vehicleSpecificationsListData.size();
                 i++) {
 
                VehicleSpecifications vehicleSpecifications
                    = vehicleSpecificationsListData.get(i);
 
                // Print and display commands
                System.out.println(
                    "Color .."
                    + vehicleSpecifications.getColor());
                System.out.println(
                    "Name .."
                    + vehicleSpecifications.getName());
                System.out.println(
                    "Price .."
                    + vehicleSpecifications.getPrice());
                System.out.println(
                    "Type .."
                    + vehicleSpecifications.getType());
            }
            // Closing the resources to free up memory space
            vehicleObjectInputStream.close();
        }
 
        // Catch block to handle the exceptions
 
        // Catch block 1
        // Handling input output  exceptions
        catch (IOException ex) {
 
            // Printing the line number where exception
            // occured using printStackTrace() method
            ex.printStackTrace();
        }
 
        // Catch block 2
        // Handle exception if class not found
        catch (ClassNotFoundException e) {
 
            // Again, printing the line number where
            // exception occured using printStackTrace()
            // method
            e.printStackTrace();
        }
    }
}


示例 2:

Java

// Class 2
// Java Program to Create Few VehicleSpecifcation and
// Writing in a File
 
// Importing required classes from packages
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class VehicleSpecificationsSerializer {
 
    // main driver method
    public static void main(String[] args)
    {
 
        // Output file been passed in a string
        String sampleOutputFile = "VehicleSpecifcation.db";
 
        // Try block to check for exceptions
        try {
 
            // Create a objectoutputstream accepting the
            // file name as VehicleSpecifcation.db
            ObjectOutputStream vehicleObjectOutput
                = new ObjectOutputStream(
                    new FileOutputStream(sampleOutputFile));
 
            // Create a list of VehicleSpecifications class
            List listSpecifications
                = new ArrayList();
 
            // Add the necessary data using standard add()
            // method Custom input
            listSpecifications.add(
                new VehicleSpecifications("Radiant Red",
                                          "SUV", "WR-V",
                                          1700000f));
 
            listSpecifications.add(
                new VehicleSpecifications("Metallic Blue",
                                          "SUV", "WR-V",
                                          1800000f));
 
            listSpecifications.add(
                new VehicleSpecifications(
                    "Black", "SUV", "WR-V", 1900000f));
 
            // We are writing the whole object into the file
            // which is a list item of VehicleSpecifications
            // object
            vehicleObjectOutput.writeObject(
                listSpecifications);
 
            // Closing the connection to release memory
            vehicleObjectOutput.close();
        }
 
        // Catch block to handle the exceptions
        catch (IOException ex) {
 
            // Print the exceptions along with line number
            // using printStackTrace() method
            ex.printStackTrace();
        }
    }
}

注意:在执行上面的代码时,我们可以看到数据是以二进制格式写入的,这意味着它只是一种不可读的格式。

所以为了以可读的格式获取数据,我们使用ObjectInputStream,因为我们必须检索类对象数据(即VehicleSpecifications数据),我们需要使用readObject ()方法,该方法可以使用read()读取类属性ObjectInputStream提供的方法。

示例 3:

Java

// Java Program to make above code human-readable
 
// Importing classes from required packages
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
 
// Main class
public class VehicleSpecificationsDeSerializer {
 
    // main driver method
    public static void main(String[] args)
    {
 
        // Input file
        String sampleInputFile = "VehicleSpecifcation.db";
 
        // Try block to check for exceptions
        try {
 
            // Creating an object of ObjectInputStream class
            ObjectInputStream vehicleObjectInputStream
                = new ObjectInputStream(
                    new FileInputStream(sampleInputFile));
 
            // Creating a List class object
            // Declaring object of user defined type
            // (VehicleSpecifications)
            List
                vehicleSpecificationsListData
                = new ArrayList();
 
            // Using readObject, bringing back the whole
            // list item of VehicleSpecifications into scope
 
            // readObject which can read class attributes
            // using read methods provided by
            // ObjectInputStream.
            vehicleSpecificationsListData
                = (ArrayList)
                      vehicleObjectInputStream.readObject();
 
            // Iterating over above object created
            for (int i = 0;
                 i < vehicleSpecificationsListData.size();
                 i++) {
 
                VehicleSpecifications vehicleSpecifications
                    = vehicleSpecificationsListData.get(i);
 
                // Print and display commands
                System.out.println(
                    "Color .."
                    + vehicleSpecifications.getColor());
                System.out.println(
                    "Name .."
                    + vehicleSpecifications.getName());
                System.out.println(
                    "Price .."
                    + vehicleSpecifications.getPrice());
                System.out.println(
                    "Type .."
                    + vehicleSpecifications.getType());
            }
            // Closing the resources to free up memory space
            vehicleObjectInputStream.close();
        }
 
        // Catch block to handle the exceptions
 
        // Catch block 1
        // Handling input output  exceptions
        catch (IOException ex) {
 
            // Printing the line number where exception
            // occured using printStackTrace() method
            ex.printStackTrace();
        }
 
        // Catch block 2
        // Handle exception if class not found
        catch (ClassNotFoundException e) {
 
            // Again, printing the line number where
            // exception occured using printStackTrace()
            // method
            e.printStackTrace();
        }
    }
}

输出:

输出说明:

因此,我们看到的是人类可读格式的输出。因此,我们的整个类对象集可以使用Java.io 包提供的 ObjectInput 和 ObjectOutput 流进行移植。因此,现在让我们在对 ObjectOutputStream 和 ObjectInputStream 的内部工作流程有一个了解之后,最终讨论它们之间的区别。它们以表格格式显示如下:

ObjectOutputStream ObjectInputStream
Writes Java objects  Reads Java objects
Using ArrayList, we can write multiple Java objects Via ArrayList, we can read and retrieve multiple Java objects
By default, ArrayList is serializable, and hence no need to implement serializable if we are writing ArrayList of objects like String, but the elements should be serializable. writeObject() is used to write ArrayList of data During deserialization of ArrayList object, readObject() is used to read the ArrayList of data
If we are using a class object(like the example as we discussed above), the class should implement serializable and then only while using writeObject() method, java.io.NotSerializableException will not be thrown We need to cast the same format of object while using readObject()
writeObject() method writes the serialized data in binary format readObject() method deserializes and reads the data
The binary format is not readable. Though we are passing primitive data like String, double, etc., while writing, the data is getting stored in binary format. In order to get the data in perfect class format, we need to use ObjectInputStream which deserializes data and we can get all primitive data that is written
As a whole object, it is getting written, there is no loss of data provided the object is serialized and written in a proper format Similarly, whole object is read, there is no loss of data, and we can easily iterate the data also.

Not only writing class objects by means writeObject(), it also supports other write methods like as depicted below and many more methods to write for each and every data type.

 write(byte[] buffer)-> Writes an array of bytes.

writeBoolean(boolean value) -> Write boolean value

writeDouble(double value)-> Write 64 bit double value

writeInt(int value)-> Writes 32 bit int 

Not only reading class objects by means readObject(), it also supports other read methods like depicted as below and many more methods to read each and every datatype.

read()-> Reads byte of data

readBoolean() -> To read  a boolean.

readDouble()-> To read a 64 bit double.

readInt()->To Read a 32 bit int.

Possible exceptions for ObjectOutputStream is as follows:

IOException – in case of any I/O error occurs during writing stream header

SecurityException 

NullPointerException – if OutputStream not initialized and hence it may be null

Possible exceptions for ObjectInputStream is as follows:

StreamCorruptedException – Incorrect stream header

IOException – In case of any I/O error occurs while reading stream header

SecurityException 

NullPointerException – if Inputstream not initialized and hence it may be null

Possible exceptions for writeObject is as follows:

InvalidClassException – Serialization of class should be correct and if something is wrong.

NotSerializableException – Some object to be serialized does not implement the java.io.Serializable interface. This will commonly occur and hence it is mandatory to make the class to implement Serializable

IOException – During writing, if IO error occur by the underlying OutputStream.

Possible exceptions for readObject is as follows:

InvalidClassException – Serialization of class should be correct and if something is wrong.

ClassNotFoundException – Class of a serialized object should be available and if cannot be found.

IOException – During reading, if IO error occur by the underlying InputStream

StreamCorruptedException 

OptionalDataException