CS F213 Objected Oriented Programming Labsheet 9
Spring 2024
I/O in Java
Java I/O (Input and Output) is used to process the input and produce the output.
Java uses the concept of a stream
to make I/O operation fast. The java.io
package contains all the classes required for input and output operations. We can perform file handling in Java by Java I/O API
Stream
A stream is a sequence of data. It's called a stream because it is like a stream of water that continues to flow. A stream can produce or consume information and is linked to a physical device (keyboard, mouse, monitor, network socket, etc.)
In Java, 3 streams are created for us automatically. All these streams are attached with the console
.
System.out: standard output stream
System.in: standard input stream
System.err: standard error stream
Java provides two types of streams:
Byte streams
Character streams
Java Console class
The Java Console class is be used to get input from console. It provides methods to read texts and passwords. If you read password using Console class, it will not be displayed to the user. The java.io.Console
class is attached with system console internally.
Java Console class methods
Reader reader()
It is used to retrieve the reader object associated with the console
String readLine()
It is used to read a single line of text from the console
String readLine(String fmt, Object... args)
It provides a formatted prompt then reads the single line of text from the console
char[] readPassword()
It is used to read password that is not being displayed on the console
char[] readPassword(String fmt, Object... args)
It provides a formatted prompt then reads the password that is not being displayed on the console
Console format(String fmt, Object... args)
It is used to write a formatted string to the console output stream
Console printf(String format, Object... args)
It is used to write a string to the console output stream
PrintWriter writer()
It is used to retrieve the PrintWriter object associated with the console
void flush()
It is used to flush the console
Example
Java Console Example to read password
Java Reader and Writer class
Java Reader is an abstract class for reading character streams. The only methods that a subclass must implement are read(char[], int, int)
and close()
. Most subclasses, however, will override some of the methods to provide higher efficiency, additional functionality, or both.
Eample
Java Writer is an abstract class for writing to character streams. The methods that a subclass must implement are write(char[], int, int)
, flush()
, and close()
. Most subclasses will override some of the methods defined here to provide higher efficiency, functionality or both.
Eample
Output.txt will contain the text "Content for output" afterwards
Java BufferedReader and BufferedWriter class
Java BufferedReader class is used to read the text from a character-based input stream. It can be used to read data line by line by readLine()
method. It makes the performance fast. It inherits Reader class.
In this example, we are reading the data from the text file file.txt using Java BufferedReader class.
Output will contain the contents of file.txt
An InputStreamReader
is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.
Reading data from console by InputStreamReader and BufferedReader until user writes stop
Java BufferedWriter class is used to provide buffering for Writer instances. It makes the performance fast. It inherits Writer class. The buffering characters are used for providing the efficient writing of single arrays, characters, and strings.
This will print Success and write the text "Welcome" to testout.txt
Reading and Writing Files by FileInputStream and FileOutputStream
Java FileInputStream class obtains input bytes from a file. It is used for reading byte-oriented data (streams of raw bytes) such as image data, audio, video etc. You can also read character-stream data. But, for reading streams of characters, it is recommended to use FileReader class.
Example to read all characters from a file
Java FileOutputStream is an output stream used for writing data to a file. If you have to write primitive values into a file, use FileOutputStream class. You can write byte-oriented as well as character-oriented data through FileOutputStream class. But, for character-oriented data, it is preferred to use FileWriter than FileOutputStream.
Reading and Writing Files by FileWriter and FileReader
Java FileReader class is used to read data from the file. It returns data in byte format like FileInputStream class. It is character-oriented class which is used for file handling in java.
Example
Java FileWriter class is used to write character-oriented data to a file. It is character-oriented class which is used for file handling in java. Unlike FileOutputStream class, you don't need to convert string into byte array because it provides method to write string directly.
Example
Serialization and Deserialization in Java
Serialization in Java is a mechanism of writing the state of an object into a byte-stream. It is mainly used in Hibernate, RMI (Remote Method Invocation) and JPA (Java Persistence API) technologies.
The reverse operation of serialization is called deserialization where byte-stream is converted into an object. The serialization and deserialization process is platform-independent, it means you can serialize an object on one platform and deserialize it on a different platform.
For serializing the object, we call the writeObject() method of ObjectOutputStream class, and for deserialization we call the readObject() method of ObjectInputStream class.
We must have to implement the Serializable interface for serializing the object.
ObjectOutputStream class
The ObjectOutputStream class is used to write primitive data types, and Java objects to an OutputStream. Only objects that support the java.io.Serializable interface can be written to streams.
ObjectInputStream class
An ObjectInputStream deserializes objects and primitive data written using an ObjectOutputStream.
Example for Serialization
Deserialization is the process of reconstructing the object from the serialized state. It is the reverse operation of serialization. Let's see an example where we are reading the data from a deserialized object.
Example for Deserialization
transient keyword
During the serialization, when we do not want an object to be serialized we can use a transient
keyword. The transient keyword can be used with the data members of a class in order to avoid their serialization. For example, if a program accepts a user's login details and password. But we don't want to store the original password in the file. Here, we can use transient keyword and when JVM reads the transient keyword it ignores the original value of the object and instead stores the default value of the object.
If you deserialize the serialized object, you will get the default value for transient variable
Eample
Exercises
Exercise 1
Student Record Management
Problem Statement: You are tasked with developing a student record management system. The system should allow users to input student details, such as name, roll number, and marks, and store them in a file student.txt
Users should also be able to retrieve and display the student records from the file. You have to use BufferedReader, BufferedWriter, InputStreamReader, FileWriter and FileReader to achieve the task.
Sample I/O
Exercise 2
Problem Statement: You are working on an employee management system. Implement serialization and deserialization to store and retrieve employee objects. The system should allow users to add new employee records (Name, Id, Department and salary), serialize them to a file, and retrieve and display the employee records from the file using deserialization. However, the department variable in the Employee class that should not be serialized.
Make two classes, one Employee that implements Serializable, and another Main to make ObjectOutputStream and ObjectInputStream for serializing and deserializing the file.
Sample I/O
Notice that department was not serialized and therfore while printing it's value is null
While both exercises involve reading and writing data to/from a file, serialization provides some distinct advantages over plain file I/O when it comes to handling complex object structures. Here's an example that illustrates the advantages of serialization:
Consider a scenario where you have a system that manages a collection of objects representing different shapes, such as circles, rectangles, and triangles. Each shape object has its own set of properties like dimensions, color, and position.
Without serialization: If you were to store the shape objects in a file using plain file I/O, you would need to come up with a custom file format and define your own rules for reading and writing each shape's properties. For example, you might choose a CSV (Comma-Separated Values) format where each line represents a shape and each value represents a property. While this approach is feasible, it requires significant manual effort to correctly parse and format the data for each shape type.
With serialization: By using serialization, you can simply serialize the entire collection of shape objects and write them to a file as a single unit. The serialization process automatically handles the conversion of the complex object structure into a byte stream, which can be directly written to a file. Similarly, during deserialization, the byte stream is read from the file and reconstructed back into the original object structure.
Exercise 3
Problem Statement: You are building a Shape Collection application that manages a collection of various shapes, including circles, rectangles, and triangles. Implement serialization and deserialization to store and retrieve the shape objects. Your task is to complete the program by adding serialization support to the Shape class hierarchy.
Instructions:
Implement the Serializable interface in each shape class (Circle, Rectangle, and Triangle) to enable serialization.
Ensure that all necessary properties and methods required to represent each shape are present in their respective classes.
Implement the ShapeCollection class, which will serve as the container for the shape objects. This class should have methods to add shapes, serialize the shape collection to a file (use FileReader and FileWriter to do so), and deserialize the shape collection from a file.
Test your implementation by adding multiple shapes to the collection, serializing the collection to a file, and then deserializing it to retrieve and display the shapes.
Sample I/O
Last updated