Interactive Input and Output in File Handling

Introduction

File handling is a crucial aspect of any programming language, including Java. It enables developers to interact with the file system, allowing the creation, reading, updating, and deletion of files. Through interactive input and output in file handling, Java programs can dynamically respond to user input, making them more versatile and user-friendly. This process involves leveraging Java's file I/O classes from the java.io package, such as File, FileReader, FileWriter, BufferedReader, and BufferedWriter. By understanding how to manage file I/O operations interactively, developers can build applications that handle data persistently, read user inputs from files, and write outputs back to files, thus facilitating a more interactive and efficient user experience.

Interactive Input and Output 

We often generate data for writing to files within programs or use data from other files stored in memory. But what if the data needs to be provided through the keyboard? In Java, this can be accomplished by using an object of the DataInputStream class. The process of reading data from the keyboard and displaying output on the screen is known as interactive I/O. There are two types of interactive I/O. The first type is simple interactive I/O, which involves basic input from the keyboard and basic output in pure text form. The second type is graphical interactive I/O, which involves input from various devices and output to a graphical environment on frames and applets.

Simple Input and Output

The System class contains three i/o objects, namely System.in, System.out and System.err where in, out and err are static variables. The variable in is of InputStream type and the other two are of PrintStream type. We can use these objects to input from the keyboard, output to the screen, and display error messages. System class is stored in java.lang package which is imported into a Java program automatically.

To perform keyboard input for primitive data types, we need to use the objects of the DataInputStream and StirngTokenizer classes.

The following code illustrates the reading of an integer value from the keyboard.

static DataInputStream dins=new DataInputStream(System.in);
static Stirng Tokenizer st1;
---------------------------
--------------------------
st1=new StringTokenizer (dins.readLine);
int code=Integer.parseInt(st1.nextToken);

The first line of code wraps dins over the input stream System.in thus enabling the object din to read data from the keyboard. For example, the method call.

dins.readLine() will fetch an entire string (up to a newline, which will be discarded) from the console. The statement

st1=new StringTokenizer(dins.readLine());

Initializes the StringTokenizer object st1 with the string read by readLine() method. Finally, the line 

int code=Integer.parseInt(st1.nextToken);

Takes the string, converts it into the corresponding integer value, and then assigns the result to the integer type variable code. A similar algorithm may be used for reading all the other primitive-type data from the console.

Program demonstrates how data is read from the keyboard for writing to a file and how the data is read back from the file for display on the screen.

Source Code

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

class Inventory {
    static DataInputStream din = new DataInputStream(System.in);
    static StringTokenizer st;

    public static void main(String args[]) throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("invent.dat"));

        // Reading from console
        System.out.println("Enter code number");
        st = new StringTokenizer(din.readLine());
        int code = Integer.parseInt(st.nextToken());

        System.out.println("Enter number of items");
        st = new StringTokenizer(din.readLine());
        int items = Integer.parseInt(st.nextToken());

        System.out.println("Enter cost");
        st = new StringTokenizer(din.readLine());
        double cost = Double.parseDouble(st.nextToken());

        // Writing to the file "invent.dat"
        dos.writeInt(code);
        dos.writeInt(items);
        dos.writeDouble(cost);
        dos.close();

        // Processing data from the file
        DataInputStream dis = new DataInputStream(new FileInputStream("invent.dat"));
        int codeNumber = dis.readInt();
        int totalItems = dis.readInt();
        double itemCost = dis.readDouble();
        double totalCost = totalItems * itemCost;
        dis.close();

        // Writing to console
        System.out.println("Code Number: " + codeNumber);
        System.out.println("Item Cost: " + itemCost);
        System.out.println("Total Items: " + totalItems);
        System.out.println("Total Cost: " + totalCost);
    }
}

Output

Simple Input and Output

This code will read input from the console, write the data to a file named invent.dat, and then read the data back from the file to display it on the console. The process includes using StringTokenizer for parsing the input and DataInputStream and DataOutputStream for file operations.

Graphical Input and Output

The following source code create a simple sequential student file interactively using window frames. The program uses the TextField class to create text fields that receive information from the user at the keyboard and then writes the information to a file. A record of information contains roll number, name and marks obtained by a student in a test.

Source Code

import java.io.*;
import java.awt.*;
import java.awt.event.*;

class StudentFile extends Frame {
    // Defining window components
    TextField number, name, marks;
    Button enter, done;
    Label numLabel, nameLabel, markLabel;
    DataOutputStream dos;

    // Initialize the Frame
    public StudentFile() {
        super("Create Student File");
    }

    // Setup the window
    public void setup() {
        setSize(400, 200);
        setLayout(new GridLayout(4, 2));
        
        // Create the components of the Frame
        number = new TextField(25);
        numLabel = new Label("Roll Number");
        name = new TextField(25);
        nameLabel = new Label("Student name");
        marks = new TextField(25);
        markLabel = new Label("Marks");
        enter = new Button("ENTER");
        done = new Button("DONE");

        // Add the components to the Frame
        add(numLabel);
        add(number);
        add(nameLabel);
        add(name);
        add(markLabel);
        add(marks);
        add(enter);
        add(done);

        // Show the Frame
        setVisible(true);

        // Open the file
        try {
            dos = new DataOutputStream(new FileOutputStream("student.dat"));
        } catch (IOException e) {
            System.err.println(e.toString());
            System.exit(1);
        }

        // Add event listeners
        enter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                addRecord();
            }
        });

        done.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                cleanup();
                System.exit(0);
            }
        });
    }

    // Write to the file
    public void addRecord() {
        int num;
        double d;
        try {
            num = Integer.parseInt(number.getText());
            dos.writeInt(num);
            dos.writeUTF(name.getText());
            d = Double.parseDouble(marks.getText());
            dos.writeDouble(d);

            // Clear the text fields
            number.setText("");
            name.setText("");
            marks.setText("");
        } catch (IOException | NumberFormatException e) {
            System.err.println(e.toString());
        }
    }

    // Adding the record and clearing the TextFields
    public void cleanup() {
        try {
            dos.flush();
            dos.close();
        } catch (IOException e) {
            System.err.println(e.toString());
        }
    }

    // Execute the program
    public static void main(String[] args) {
        StudentFile student = new StudentFile();
        student.setup();
    }
}

Output

Graphical Input and Output

This Java program creates a GUI for entering student records with fields for roll number, name, and marks. The records are saved to a file named "student.dat". The program provides buttons to enter records and finish the process, ensuring the data is written to the file properly and the text fields are cleared after each entry.

The program uses classes Frame, TextField, Button, and Label from the java.awt package to create the window and the text fields required to receive a student record. The setup() method sets up the window. The addRecord() method writes the information to the "student.dat" file. After entering the data in the appropriate text fields, clicking the ENTER button writes the data to the file by invoking the addRecord() method. When the DONE button is clicked, the program calls the cleanup() method, which closes the file stream and terminates the program execution.

Below is the source code for reading the data stored in the "student.dat" file created by the previous program. This program opens the file for reading and sets up a window similar to the one created for writing. When the NEXT button is clicked, the program reads a record from the file and displays its content in the text fields of the window. Clicking the DONE button closes the file stream and terminates the execution.

Source Code

import java.io.*;
import java.awt.*;

class ReadStudentFile extends Frame {
    // Defining window components
    TextField number, name, marks;
    Button next, done;
    Label numLabel, nameLabel, markLabel;
    DataInputStream dis;
    boolean moreRecords = true;

    // Initialize the Frame
    public ReadStudentFile() {
        super("Create Student File");
    }

    // Setup the window
    public void setup() {
        resize(400, 200);
        setLayout(new GridLayout(4, 2));

        // Create the components of the Frame
        number = new TextField(25);
        numLabel = new Label("Roll Number");
        name = new TextField(25);
        nameLabel = new Label("Student Name");
        marks = new TextField(25);
        markLabel = new Label("Marks");
        next = new Button("NEXT");
        done = new Button("DONE");

        // Add the components to the Frame
        add(numLabel);
        add(number);
        add(nameLabel);
        add(name);
        add(markLabel);
        add(marks);
        add(next);
        add(done);

        // Show the Frame
        show();

        // Open the file
        try {
            dis = new DataInputStream(new FileInputStream("student.dat"));
        } catch (IOException e) {
            System.err.println(e.toString());
            System.exit(1);
        }
    }

    // Read from the file
    public void readRecord() {
        int n;
        String s;
        double d;
        try {
            n = dis.readInt();
            s = dis.readUTF();
            d = dis.readDouble();
            number.setText(String.valueOf(n));
            name.setText(String.valueOf(s));
            marks.setText(String.valueOf(d));
        } catch (EOFException e) {
            moreRecords = false;
        } catch (IOException ioe) {
            System.out.println("IO Error");
            System.exit(1);
        }
    }

    // Closing the input file
    public void cleanup() {
        try {
            dis.close();
        } catch (IOException e) {
        }
    }

    // Processing the event
    public boolean action(Event event, Object o) {
        if (event.target instanceof Button) {
            if (event.arg.equals("NEXT")) {
                readRecord();
            }
            return true;
        }
        return false;
    }

    public boolean handleEvent(Event event) {
        if (event.target instanceof Button) {
            if (event.arg.equals("DONE") || moreRecords == false) {
                cleanup();
                System.exit(0);
                return true;
            }
        }
        return super.handleEvent(event);
    }

    // Execute the program
    public static void main(String args[]) {
        ReadStudentFile student = new ReadStudentFile();
        student.setup();
    }
}

The Java program 'ReadStudentFile creates a graphical user interface (GUI) to read and display student information from a file named student.dat. The class extends Frame, enabling it to create a windowed application. The GUI comprises text fields for displaying the student's roll number, name, and marks alongside labels for each field. Two buttons, "NEXT" and "DONE", are provided to navigate through the records and to exit the program, respectively. The setup method initializes the GUI components, sets their layout, and attempts to open the student.dat file using a DataInputStream.

The readRecord method reads data from the file and displays it in the respective text fields. It handles EOFException to detect the end of the file and sets a flag accordingly. The cleanup method closes the file input stream. Event handling is managed by the action and handleEvent methods, which respond to button clicks, invoking readRecord for the "NEXT" button and terminating the program if "DONE" is clicked or no more records are available. The main method initiates the program by creating an instance of ReadStudentFile and calling its setup method.

Summary 

Interactive input and output in file handling with Java integrates the language's file I/O capabilities with graphical user interfaces (GUIs) to provide an intuitive way for users to interact with data stored in files. Utilizing Java's Abstract Window Toolkit (AWT) and Swing, developers can create applications with text fields, labels, and buttons that allow users to view and navigate through file contents. Event handling mechanisms enable the program to respond to user actions, such as clicking "NEXT" to read the next record or "DONE" to close the file and exit the program. This approach combines efficient data processing with a user-friendly interface, making it ideal for applications that require direct user interaction with file data.