Class ObjectInputStream in Java

0
69
digitization, transformation, binary
Spread the love

Class ObjectInputStream in Java

ObjectInputStream is used to deserialize objects, arrays, and other values from a stream that was previously created with an ObjectOutputStream.The ObjectInputStream class can read both primitive types and object instances from an underlying InputStream.

ObjectInputStream and ObjectOutputStream classes can provide persistent storage of objects when they are used in conjunction with FileInputStream and FileOutputStream. The classes can also be used with socket streams to pass objects across the network.

The readObject() method deserializes objects and arrays (which should then be cast to the appropriate type); various other methods are used to read primitive data values from the stream.

Only objects that are instances of classes that implement the Serializable or Externalizable interfaces can be deserialized from an input stream. The default deserialization mechanism is implemented by readObject().

When an object is deserialized, the non-static and non-transient fields of the object are restored to the values they had when the object was serialized, including any other objects referenced by the object (except for those objects that do not implement the Serializable interface themselves).

Graphs of objects are restored using a reference sharing mechanism. New object instances are always allocated during the deserialization process, to prevent existing objects from being overwritten.

Deserialized objects are returned as instances of type Object, so they should be cast to the appropriate type. Strings and arrays are objects in Java, so they are treated as objects during deserialization.

Note Only objects that implement the Serializable interface or the Externalizable interface can be serialized and deserialized.

The defaultReadObject() method may only be called from the readObject() method of an object that is currently being deserialized.

It allows an object to perform additional processing after deserializing itself. The registerValidation() method may also only be called from the readObject() method of an object being deserialized.

It registers an ObjectInputValidation object (typically the object being deserialized) to be notified when a complete tree of objects has been deserialized and the original call to the readObject() method of the ObjectInputStream is about to return to its caller.

The remaining methods include miscellaneous stream manipulation methods and several protected methods for use by subclasses that want to customize the deserialization behavior of ObjectInputStream.

The class structure for the class ObjectInputStream is given as

public class java.io.ObjectInputStream extends java.io.InputStream implements java.io.ObjectInput {
// Public Constructor
public ObjectInputStream(InputStream in) throws IOException,StreamCorruptedException;
// Public Instance Methods
public int available() throws IOException; // Overrides InputStream
public void close() throws IOException; // Overrides InputStream
public final void defaultReadObject() throws IOException,ClassNotFoundException, NotActiveException;
public int read() throws IOException; // Defines InputStream
public int read(byte[] data, int offset, int length) throws IOException;// Overrides InputStream
public boolean readBoolean() throws IOException; // From DataInput
public byte readByte() throws IOException; // From DataInput
public char readChar() throws IOException; // From DataInput
public double readDouble() throws IOException; // From DataInput
public float readFloat() throws IOException; // From DataInput
public void readFully(byte[] data) throws IOException; // From DataInput
public void readFully(byte[] data, int offset, int size) throws IOException; // From DataInput
public int readInt() throws IOException; // From DataInput
public String readLine() throws IOException; // From DataInput
public long readLong() throws IOException; // From DataInput
public final Object readObject() throws OptionalDataException,ClassNotFoundException,IOException;// From ObjectInput
public short readShort() throws IOException; // From DataInput
public String readUTF() throws IOException; // From DataInput
public int readUnsignedByte() throws IOException; // From DataInput
public int readUnsignedShort() throws IOException; // From DataInput
public synchronized void registerValidation(ObjectInputValidation obj,int prio)
public synchronized void registerValidation'u'throws NotActiveException,InvalidObjectException;
public int skipBytes(int len) throws IOException; // From DataInput
// Protected Instance Methods
protected final boolean enableResolveObject(boolean enable) throws SecurityException;
protected void readStreamHeader() throws IOException,StreamCorruptedException;
protected Class resolveClass(ObjectStreamClass v) throws IOException,ClassNotFoundException;
protected Object resolveObject(Object obj) throws IOException;
}

The details of the methods are as follows:

public ObjectInputStream(InputStream in) throws IOException,StreamCorruptedException;

public ObjectInputStream(InputStream in) constructor creates an ObjectInputStream that reads from the given input stream.

The constructor attempts to read the stream header, which consists of a magic number and a version number, and if something goes wrong, an appropriate exception is thrown.

If all of the bytes of the stream header are not available, the constructor does not return until they become available.

public int available() throws IOException; // Overrides InputStream

public int available() throws IOException method returns the number of bytes that can be read without having to wait for more data to become available.

This method returns the number of bytes that can be read without blocking.

public void close() throws IOException; // Overrides InputStream

public void close() method closes the stream and releases any system resources that are associated with it.

public final void defaultReadObject() throws IOException,

public final void defaultReadObject() throws IOException method reads the fields of the current object that are not static and not transient.

The method can only be called from the private readObject() method of an object that is being deserialized; it throws a NotActiveException if it is called at any other time. This method implements the default deserialization mechanism.

public int read() throws IOException; // Defines InputStream

public int read() throws IOException method reads the next byte from the stream. The method blocks until some data is available, the end of the stream is detected, or an exception is thrown.

READ  Assertion Concept Simplified In Java

This method returns the next byte of data or -1 if the end of the stream is encountered.

public int read(byte[] data, int offset, int length) throws IOException;// Overrides InputStream

public int read(byte[] data, int offset, int length) throws IOException method reads up to length bytes of input into the given array starting at index offset. The method blocks until there is some input available.

This method returns the number of bytes read or -1 if the end of the stream is encountered immediately.
Parameter
data-Array of bytes to be filled from the stream.
offset-An offset into the byte array.
length-The number of bytes to read.

public boolean readBoolean() throws IOException; // From DataInput

public boolean readBoolean() throws IOException method reads a byte as a boolean value from the underlying input stream. A byte that contains a zero is read as false. A byte that contains any other value is read as true.

The method blocks until the byte are read, the end of the stream is encountered, or an exception is thrown.

This method returns the boolean value read from the stream.

public byte readByte() throws IOException; // From DataInput

public byte readByte() throws IOException method reads a signed 8-bit value, a byte, from the underlying input stream. The method blocks until the byte are read, the end of the stream is encountered, or an exception is thrown.

This method returns the byte value read from the stream.

public char readChar() throws IOException; // From DataInput

public char readChar() throws IOException method reads a 16-bit Unicode character from the stream. The method reads two bytes from the underlying input stream and then creates a char value using the first byte read as the most significant byte.

The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the char value read from the stream.

public double readDouble() throws IOException; // From DataInput

public double readDouble() throws IOException method reads a 64-bit double quantity from the stream. The method reads a long value from the underlying input stream as if using the readLong() method.

The long value is then converted to a double using the longBitsToDouble() method in Double.

The method blocks until the necessary eight bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the double value read from the stream.

public float readFloat() throws IOException; // From DataInput

public float readFloat() throws IOException method reads a 32-bit float quantity from the stream. The method reads an int value from the underlying input stream as if using the readInt() method. The int value is then converted to a float using the intBitsToFloat() method in Float.

The method blocks until the necessary four bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the float value read from the stream.

public void readFully(byte[] data) throws IOException; // From DataInput

public void readFully(byte[] data) throws IOException method reads bytes into the given array b until the array is full. The method reads repeatedly from the underlying stream to fill the array.

The method blocks until all of the bytes are read, the end of the stream is encountered, or an exception is thrown.
Parameter
data-The array to fill.

public void readFully(byte[] data, int offset, int size) throws IOException; // From DataInput

public void readFully(byte[] data, int offset, int size) throws IOException method reads len bytes into the given array, starting at offset off. The method reads repeatedly from the underlying stream to fill the array.

The method blocks until all of the bytes are read, the end of the stream is encountered, or an exception is thrown.

Parameter
data-The array to fill.
offset-An offset into the array.
length-The number of bytes to read.

public int readInt() throws IOException; // From DataInput

public int readInt() throws IOException method reads a signed 32-bit int quantity from the stream. The method reads four bytes from the underlying input stream and then creates an int quantity, using the first byte read as the most significant byte.

The method blocks until the four bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the int value read from the stream.

public String readLine() throws IOException; // From DataInput

public String readLine() throws IOException method reads the next line of text from the stream. The method reads bytes of data from the underlying input stream until it encounters a line terminator.

READ  Abstract interface ObjectInput in Java

A line terminator is a carriage return (“\r”), a newline character (“\n”), a carriage return immediately followed by a newline character or the end of the stream.

The method blocks until a line terminator are read, the end of the stream is encountered, or an exception is thrown.

This method returns a String that contains the line read from the stream.

public long readLong() throws IOException; // From DataInput

public long readLong() throws IOException method reads a signed 64-bit long quantity from the stream. The method reads eight bytes from the underlying input stream and then creates a long quantity, using the first byte read as the most significant byte.

The method blocks until the eight bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the long value read from the stream.

public final Object readObject() throws OptionalDataException,ClassNotFoundException, IOException;

public final Object readObject() method deserializes an object from the stream and returns a reference to the object. The non-static and non-transient fields of the object are restored to the values they had when the object was serialized.

If the object contains references to other objects, these objects are also deserialized (as long as they implement the Serializable interface). Graphs of objects are restored using a reference-sharing mechanism.

New object instances are always allocated during the deserialization process, to prevent existing objects from being overwritten. Deserialized objects are returned as instances of type Object, so they should be cast to the appropriate type.

Once an object has been completely restored (i.e., all of its fields and any objects it references have been restored), any object validation callbacks for the object or any of the objects it references are called in an order based on their priority.

An object validation callback is registered by the private readObject() method for an object.

Throws
ClassNotFoundException-If the object being deserialized has an unrecognized class.
InvalidClassException-If there is a problem with the class of the deserialized object.
StreamCorruptedException-If the stream serialization information is not correct.
OptionalDataException-If the stream contains primitive data instead of an object.
IOException-If any kind of I/O error occurs.

public short readShort() throws IOException; // From DataInput

public short readShort() throws IOException method reads a signed 16-bit short quantity from the stream. The method reads two bytes from the underlying input stream and then creates a short quantity, using the first byte read as the most significant byte.

The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

This method returns the short value read from the stream.
Parameter

public String readUTF() throws IOException,EOFException,UTFDataFormatException; // From DataInput

public String readUTF() throws IOException method reads a UTF-8 encoded string from the stream.
This method returns the string read from the stream.
Throws
EOFException-If the end of the file is encountered.
IOException-If any other kind of I/O error occurs.
UTFDataFormatException-If the bytes do not represent a valid UTF-8 encoding.

public int readUnsignedByte() throws IOException; // From DataInput

public int readUnsignedByte() throws IOException method reads an unsigned 8-bit quantity from the stream. The method reads a byte from the underlying input stream and returns that byte. The method blocks until the byte are read, the end of the stream is encountered, or
the exception is thrown.
This method returns the unsigned byte value read from the stream.

public int readUnsignedShort() throws IOException; // From DataInput

public int readUnsignedShort() throws IOException method reads an unsigned 16-bit quantity from the stream. The method reads two bytes from the underlying input stream and creates an unsigned short quantity using the first byte read as the most significant byte.

The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.
This method returns the unsigned short value read from the stream.

public synchronized void registerValidation(ObjectInputValidation obj,int prio) throws NotActiveException,InvalidObjectException;

public synchronized void registerValidation(ObjectInputValidation obj,int prio) method may be called from an object’s private readObject() method to register a validation callback.

An object performs internal validation by implementing the ObjectInputValidation interface and registering itself with the ObjectInputStream via this function.

When ObjectInputStream has completely deserialized an object (i.e., restored all of its fields and any objects it references), the stream calls ObjectInputValidation.validateObject() for every object that has an object validation callback.

Objects that register with higher priority values get validated before objects that register with lower priority values. Within a priority value, the callbacks are not processed in any particular order.

Parameter

obj-The object requesting validation.
prio-The priority of the validation callback; use zero as a default.

public int skipBytes(int len) throws IOException; // From DataInput

public int skipBytes(int len) throws IOException method skips over n bytes in the underlying input stream. The method blocks until all of the bytes are skipped, the end of the stream is encountered, or an exception is thrown.

READ  Class Stack in Java

This method returns the actual number of skipped bytes.
Parameter
len-The number of bytes to skip.

protected final boolean enableResolveObject(boolean enable) throws SecurityException;

protected final boolean enableResolveObject(boolean enable) throws SecurityException method determines if a trusted subclass of ObjectInputStream is allowed to replace deserialized objects. If the method is called with true, object replacement is enabled.

Each time an object is deserialized,resolveObject() is called to give the ObjectInputStream a chance to replace the object. A trusted stream is one whose class has no ClassLoader.
This method returns true if object replacement was previously enabled; false otherwise.
Parameter
enable-A boolean value that specifies whether or not object replacement is enabled.

protected void readStreamHeader() throws IOException,StreamCorruptedException;

protected void readStreamHeader() throws IOException,StreamCorruptedException method attempts to read the stream header, which consists of a magic number and a version number. If something goes wrong, an appropriate exception is thrown.

This method is called by the constructor for ObjectInputStream and is the source of the exceptions it throws. If you subclass ObjectInputStream, you can override this method to provide your own stream header checking.

protected Class resolveClass(ObjectStreamClass v) throws IOException,ClassNotFoundException;

protected Class resolveClass(ObjectStreamClass v) throws IOException,ClassNotFoundException method attempts to find the Class object that corresponds to the supplied ObjectStreamClass. When an object is deserialized, its class information is read into an ObjectStreamClass object, which is then resolved to a Class if possible.

Subclasses of ObjectInputStream can override this method to allow classes to be fetched from alternate sources. The version of the ObjectStreamClass and the Class must match.

This method returns the Class that corresponds to the given ObjectStreamClass.
Parameter

v-The ObjectStreamClass to be resolved.

protected Object resolveObject(Object obj) throws IOException;

protected Object resolveObject(Object obj) throws IOException method is called with each deserialized object (If object replacement is enabled for this ObjectInputStream)to give the stream a chance to replace the object.

In ObjectInputStream, this method simply returns the object that was passed to it. Subclasses can override this method to provide more useful functionality.
This method returns
Parameter

obj-The object to be replaced.

Apart from these ObjectInputStream class also has inherited methods from class- Object. They are as follows:

  • clone()
  • finalize()
  • hashCode()
  • notifyAll()
  • wait()
  • wait(long, int)
  • equals(Object)
  • getClass()
  • notify()
  • toString()
  • wait(long)

Apart from these ObjectInputStream class also has inherited methods from class- InputStream. They are as follows:

  • markSupported()
  • reset()
  • mark()
  • read(byte[])
  • skip(long n)

A snippet to use this class ObjectInputStream

FileInputStream myFileIn;
ObjectInputStream oIn;
Color color;
try {
fileIn = new FileInputStream("C:\\Test\\myFile.ser");
oIn = new ObjectInputStream(myFileIn);
color = (Color)oIn.readObject();
oIn.close();
}
catch (Exception e) {
System.out.println("Error reading: " + e);
}
...
}

Classes that have transient instance variables may require special handling to reconstruct the values of these variables when objects are deserialized. Special handling may also be necessary to correctly deserialize objects that were serialized with a different version of their class than is in use when they are deserialized. Classes that require special handling during serialization and deserialization must implement the following methods (with these exact signatures):


private void readObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream stream) throws IOException;

The writeObject() method is responsible for writing the state of the object for the particular class so that it can be restored by readObject(). The readObject() method registers an object validation callback by calling registerValidation() as its first action. The readObject() method doesn’t need to handle reading the state for the object’s superclass or any of its subclasses except in the case where the superclass doesn’t itself implement the Serializable interface. In this case, the nonserializable class must have a no-argument constructor that can be called to initialize its fields, and it is the responsibility of the subclass to restore the state of its superclass.

A class that inherits the implementation of Serializable prevents itself from being serialized by defining readObject() and writeObject() methods that throw NotSerializableException objects.

If a class needs complete control over the contents and formatting of the serialized form of its objects, it should implement the Externalizable interface.

ObjectInputStream in Serialization

Let us create a class that we want to Serialize using Serializable interface.

import java.io.*;
public class MySerialization implements Serializable {
	
	public int x=5;
	transient int y=10;
	private float z= 2.0f;
	
	int getX() {
	return x;
	}
	int getY()
	{
		return y;
	}
	float getZ() {
		return z;
	}
}

Check here we have a transient data y.
Now lets us create a class that helps in Serialization


import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class MyDemoSerialization {

	public static void main(String[] args) {
		MySerialization ms= new MySerialization();
		System.out.println("value of x "+ms.getX());
		System.out.println("value of y "+ms.getY());
		System.out.println("value of z "+ms.getZ());
		try {
			FileOutputStream fos=new FileOutputStream("D:\\MyCode\\abc.ser");
			ObjectOutputStream oos=new ObjectOutputStream(fos);
			oos.writeObject(ms);
			oos.close();
			System.out.println("Serialization is done");
			
		}
		catch(Exception e) {e.printStackTrace();}
	}

}

The output of the code:
value of x 5
value of y 10
value of z 2.0
Serialization is done
the y value is printed before Serialization

Serialization data created
Serialization data created

Now let us DeSerializa the same

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

public class MyDeSerialization {

	public static void main(String[] args) {
		System.out.println("Deserialization starts");
		MySerialization ms = null;
		try {
			FileInputStream fis=new FileInputStream("D:\\MyCode\\abc.ser");
			ObjectInputStream ois=new ObjectInputStream(fis);
			 ms = (MySerialization)ois.readObject();
			ois.close();
		}
		catch(Exception e) {e.printStackTrace();}
		System.out.println("value of x "+ms.getX());
		System.out.println("value of y "+ms.getY());
		System.out.println("value of z "+ms.getZ());
	}

}

The output of the code:
Deserialization starts
value of x 5
value of y 0
value of z 2.0

Check the y value is not saved as it is transient.


Spread the love
I am the founder and owner of the blog - TechTravelHub.com, always love to share knowledge on test automation,tools,techniques and tips.I am a passionate coder of Java and VBScript.I also publish articles on Travel ideas and great honeymoon destinations.Apart from these, I am a gear-head,love to drive across India. I have shared lots of articles here on How to travel several parts of India.Customization of cars aka car modification is my another hobby.Get in touch with me on ani01104@gamil.com

LEAVE A REPLY

Please enter your comment!
Please enter your name here