Header Ads Widget

Responsive Advertisement

File Read and write of text file using Inner class


Reading and writing files in Java can be accomplished using classes from the java.io package. Inner classes provide a way to logically group classes that are only used in one place, increasing encapsulation.

Here, I'll guide you through a scenario where you use an inner class to handle file reading and writing.

Overview

  • Outer Class (FileHandler): The main class that manages file operations.
  • Inner Class (FileReaderWriter): A nested class inside FileHandler responsible for reading from and writing to a file.

Benefits of Using an Inner Class

  • Encapsulation: The inner class FileReaderWriter is encapsulated within FileHandler, making it inaccessible from outside. This prevents unintended use by other classes.
  • Logical Grouping: The FileReaderWriter class is closely related to the FileHandler class, and logically it makes sense to group them together.
  • Access to Outer Class Members: The inner class can directly access the members (fields and methods) of the outer class.

Implementation

Here’s how you can implement file reading and writing using an inner class:

java

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

 

public class FileHandler {

 

    private String filePath;

 

    // Constructor to initialize the file path

    public FileHandler(String filePath) {

        this.filePath = filePath;

    }

 

    // Inner class to handle file reading and writing

    public class FileReaderWriter {

 

        // Method to write content to a file

        public void writeToFile(String content) {

            try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {

                writer.write(content);

                System.out.println("Content written to file successfully.");

            } catch (IOException e) {

                System.out.println("An error occurred while writing to the file: " + e.getMessage());

            }

        }

 

        // Method to read content from a file

        public String readFromFile() {

            StringBuilder content = new StringBuilder();

            try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {

                String line;

                while ((line = reader.readLine()) != null) {

                    content.append(line).append("\n");

                }

                System.out.println("Content read from file successfully.");

            } catch (IOException e) {

                System.out.println("An error occurred while reading from the file: " + e.getMessage());

            }

            return content.toString();

        }

    }

 

    public static void main(String[] args) {

        // Initialize the FileHandler with a file path

        FileHandler fileHandler = new FileHandler("example.txt");

 

        // Create an instance of the inner class

        FileReaderWriter fileRW = fileHandler.new FileReaderWriter();

 

        // Write content to the file

        fileRW.writeToFile("Hello, this is a test file.\nThis file is written using Java.");

 

        // Read content from the file

        String content = fileRW.readFromFile();

        System.out.println("File Content:\n" + content);

    }

}

 

Explanation

  1. Outer Class (FileHandler):
    • It contains a private field filePath to store the path of the file.
    • The constructor initializes the filePath.
  2. Inner Class (FileReaderWriter):
    • It handles file reading and writing operations.
    • writeToFile Method: Uses BufferedWriter to write content to the specified file. It handles exceptions to ensure that the file operation is safe.
    • readFromFile Method: Uses BufferedReader to read content from the specified file. It appends each line read to a StringBuilder and returns the full content.
  3. main Method:
    • It creates an instance of FileHandler and then an instance of the inner class FileReaderWriter.
    • It writes content to the file using writeToFile.
    • It reads the content back using readFromFile and prints it to the console.

Key Concepts:

  • Encapsulation: FileReaderWriter is hidden inside FileHandler, so it's not exposed to other parts of the program.
  • Resource Management: The try-with-resources statement ensures that the file resources (BufferedWriter, BufferedReader) are automatically closed after use, preventing resource leaks.
  • Inner Class Access: The inner class can access the filePath directly without needing to pass it as a parameter, which simplifies the code.

This setup ensures that file operations are well-organized, safe, and encapsulated within the FileHandler class.

 

 

Real example of Inner class use

 

public class Main {
 public static class Student {
  public int id;
  public String courseName;
  public int marks;

  /**
   * @return the id
   */
  public int getId() {
   return id;
  }

  /**
   * @param id
   *            the id to set
   */
  public void setId(int id) {
   this.id = id;
  }

  /**
   * @return the courseName
   */
  public String getCourseName() {
   return courseName;
  }

  /**
   * @param courseName
   *            the courseName to set
   */
  public void setCourseName(String courseName) {
   this.courseName = courseName;
  }

  /**
   * @return the marks
   */
  public int getMarks() {
   return marks;
  }

  /**
   * @param marks
   *            the marks to set
   */
  public void setMarks(int marks) {
   this.marks = marks;
  }
 }

 /**
  *
  * @param array
  *            array
  * @return Map<String,Student>
  */
 @SuppressWarnings({ "unchecked", "rawtypes" })
 public static Map<String, Student> processData(ArrayList<Student> array) {
  Map<String, Student> retVal = new HashMap<String, Student>();
  Collections.sort(array, new Comparator() {
   public int compare(Object obj1, Object obj2) {
    Student e1 = (Student) obj1;
    Student e2 = (Student) obj2;
    Integer firstId = new Integer(String.valueOf(e1.getId()));
    Integer secndId = new Integer(String.valueOf(e2.getId()));
    int id = firstId.compareTo(secndId);
    int name = e1.getCourseName().compareTo(e2.getCourseName());
    if (id != 0) {
     return id;
    } else if (id == 0 && name != 0) {
     return name;
    }
    return id;
   }
  });
  int countDS = 0, countEng = 0, key = 1;
  for (Student student : array) {
   // Data Structures and English declare in Constant file
   if (student.getCourseName().equalsIgnoreCase("Data Structures")
     && countDS == 0) {
    retVal.put(String.valueOf(key), student);
    key++;
    countDS++;
   }
   if (student.getCourseName().equalsIgnoreCase("English")
     && countEng == 0) {
    retVal.put(String.valueOf(key), student);
    key++;
    countEng++;
   }
  }
  countDS = 0;
  countEng = 0;
  key = 1;
  return retVal;
 }

 public static void main(String[] args) {
  ArrayList<Student> studentCourseList = new ArrayList<Student>();
  String line;
  try {
   @SuppressWarnings("resource")
   Scanner in = new Scanner(new BufferedReader(new FileReader(
     "input.txt")));
   while (in.hasNextLine()) {
    // inputData.add(in.nextLine());
    line = in.nextLine();
    String[] student = line.split("\\|");
    Main.Student stdnt = new Main.Student();
    stdnt.setId(Integer.parseInt(student[0]));
    stdnt.setCourseName(student[1]);
    stdnt.setMarks(Integer.parseInt(student[2]));
    studentCourseList.add(stdnt);
   }
   Map<String, Student> retVal = processData(studentCourseList);
   PrintWriter output = new PrintWriter(new BufferedWriter(
     new FileWriter("output.txt")));
   for (Map.Entry<String, Student> entry : retVal.entrySet()) {
    Student st = entry.getValue();
    output.write(st.getCourseName() + ": " + st.getMarks());
    output.println();
   }
   // output.println(e.getKey() + ": " + e.getValue());
   output.close();
  } catch (IOException e) {
   System.out.println("IO error in input.txt or output.txt");
  }
 }
}

 

The Java program you've shared reads data from an input.txt file, processes it according to specific criteria, and writes the output to an output.txt file. Let's break it down into its components and understand how it works.

Overview of the Program

  1. Student Class:
    • A nested static class Student with three fields: id, courseName, and marks.
    • Standard getter and setter methods are provided to access and modify these fields.
  2. processData Method:
    • This method processes a list of Student objects (ArrayList<Student>) and returns a Map<String, Student>, which holds selected Student objects based on the course name.
    • The students are first sorted by id and then by courseName.
    • Only one student per course ("Data Structures" and "English") is retained in the output map.
  3. Main Method:
    • Reads student data from input.txt, creates Student objects, and adds them to an ArrayList<Student>.
    • Calls processData to process the list.
    • Writes the result to output.txt.

Step-by-Step Breakdown

  1. Reading the File:
    • The program uses Scanner to read each line of the input.txt file.
    • Each line is split by the delimiter |, creating an array that holds the student's id, courseName, and marks.
  2. Creating Student Objects:
    • For each line, a new Student object is created and populated with the data from the array.
    • These Student objects are then added to the ArrayList<Student> named studentCourseList.
  3. Processing the Data:
    • The processData method sorts the students by id and then by courseName.
    • It selects the first student it encounters for each of the courses "Data Structures" and "English" and adds them to the result map (retVal).
  4. Writing to the Output File:
    • The result map is iterated over, and the selected course names and marks are written to output.txt.

Example Input and Output

input.txt:

1|Data Structures|85

2|English|90

1|English|88

3|Data Structures|75

 

output.txt (after processing):

Data Structures: 85

English: 90

 

Explanation of Key Parts:

  • Sorting:
    • The sorting is done using an anonymous Comparator class.
    • Students are sorted first by id and then by courseName. If the ids are different, the comparison returns their difference. If the ids are the same, the courseName is used for sorting.
  • Course Selection:
    • The program selects only the first occurrence of "Data Structures" and "English" after sorting. This is controlled by the countDS and countEng flags to ensure only the first encountered course is processed.
  • File Handling:
    • The program uses BufferedReader and FileReader to read input and BufferedWriter and FileWriter to write output, ensuring efficient file operations.

Notes and Improvements:

  • Generics: The Comparator could be improved by using generics to avoid the need for unchecked casts.
  • Exception Handling: The program catches IOException, but other potential exceptions (like NumberFormatException when parsing id and marks) should also be handled.
  • File Paths: Consider using relative paths or configuration for file locations, or better yet, pass file paths as command-line arguments to make the program more flexible.
  • Method Overloading: The processData method could be overloaded or parameterized to handle different course names, not just "Data Structures" and "English".

This program demonstrates basic file I/O, sorting with a custom comparator, and using an inner class to represent structured data in Java.

 





File Read and write of text file using Inner class
File Read and write of text file using Inner class




Post a Comment

0 Comments