javafile-management

How do I edit multiple .txt files in Java


I'm trying to make a GradeManager class in Java for school. I need to:

  1. Enter the students name

  2. Find student file based on name entered (I have 4 students)

  3. Edit grades that are within the file

File example: John,123456789,10,8,7,87,91 (Name,ID,Q1,Q2,Q3,Midterm,Final) and would edit Q1-Final

I don't quite understand how I would be able to get all 4 student files into editStuGrades() without having them all in one file

This is what I got:

public class GradeManager {
    private static Scanner command = new Scanner(System.in);

    public static void main(String[] args) throws Exception {
        System.out.println("Enter a students name: ");
        String commandInput = command.next();
        if (commandInput.equalsIgnoreCase("John")) {
            String filepath = FileSystems.getDefault().getPath("src", "Assignments", "John.txt").toAbsolutePath().toString();
            File inputFile = new File(filepath);
            Scanner line = new Scanner(inputFile);
            while (line.hasNext()) {
                String rLine = line.nextLine();
                String name = rLine.substring(0, rLine.indexOf(","));
                System.out.println("Name: " + name + " | ");
                editStuGrade();
            }

        }
        if (commandInput.equalsIgnoreCase("Matthew")) {
            String filepath = FileSystems.getDefault().getPath("src", "Assignments", "Matthew.txt").toAbsolutePath().toString();
            File inputFile = new File(filepath);
            Scanner line = new Scanner(inputFile);
            while (line.hasNext()) {
                String rLine = line.nextLine();
                String name = rLine.substring(0, rLine.indexOf(","));
                System.out.println("Name: " + name + " | " );
                editStuGrade();
            }

        }
    }
    public static void editStuGrade() {
        System.out.println("Would you like to edit or quit (edit | quit)?");
        String editInput = command.next();
        if (editInput.equalsIgnoreCase("edit")) {

        } else if (editInput.equalsIgnoreCase("quit")) {
            System.exit(0);
        }


    }
}

Solution

  • Start by taking a look at Passing Information to a Method or a Constructor

    What you want to (try and do) is to make the core functionality "common". Let's face it, reading and writing the student data is basically the same for all the students, the only difference is, the source and destination.

    To this end, I'd start with a POJO (plain old Java object), for example...

    public class Student {
    
        private String name;
        private String id;
        private int q1Score;
        private int q2Score;
        private int q3Score;
        private int midTermScore;
        private int finalScore;
    
        public Student(String name, String id, int q1Score, int q2Score, int q3Score, int midTermScore, int finalScore) {
            this.name = name;
            this.id = id;
            this.q1Score = q1Score;
            this.q2Score = q2Score;
            this.q3Score = q3Score;
            this.midTermScore = midTermScore;
            this.finalScore = finalScore;
        }
    
        public static Student loadByName(String name) throws IOException {
            File file = new File(name + ".txt");
            if (!file.exists()) {
                throw new FileNotFoundException("No record exists for " + name);
            }
    
            try (Scanner input = new Scanner(file)) {
                input.useDelimiter(",");
                name = input.next();
                String id = input.next();
                int q1Score = input.nextInt();
                int q2Score = input.nextInt();
                int q3Score = input.nextInt();
                int midTermScore = input.nextInt();
                int finalScore = input.nextInt();
    
                return new Student(name, id, q1Score, q2Score, q3Score, midTermScore, finalScore);
            }
        }
        
        public void save() throws IOException {
            File file = new File(getName() + ".txt");
            StringJoiner joiner = new StringJoiner(",");
            joiner.add(getName());
            joiner.add(getId());
            joiner.add(Integer.toString(getQ1Score()));
            joiner.add(Integer.toString(getQ2Score()));
            joiner.add(Integer.toString(getQ3Score()));
            joiner.add(Integer.toString(getMidTermScore()));
            joiner.add(Integer.toString(getFinalScore()));
            
            try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
                bw.write(joiner.toString());
            }
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public int getQ1Score() {
            return q1Score;
        }
    
        public void setQ1Score(int q1Score) {
            this.q1Score = q1Score;
        }
    
        public int getQ2Score() {
            return q2Score;
        }
    
        public void setQ2Score(int q2Score) {
            this.q2Score = q2Score;
        }
    
        public int getQ3Score() {
            return q3Score;
        }
    
        public void setQ3Score(int q3Score) {
            this.q3Score = q3Score;
        }
    
        public int getMidTermScore() {
            return midTermScore;
        }
    
        public void setMidTermScore(int midTermScore) {
            this.midTermScore = midTermScore;
        }
    
        public int getFinalScore() {
            return finalScore;
        }
    
        public void setFinalScore(int finalScore) {
            this.finalScore = finalScore;
        }
    
    }
    

    nb: You could just use an array, but where's the fun in that

    So, the above is just a container for the data we want to manage. It provides two convince methods for reading and writing the student information, so we don't "repeat" code and introduce possible bugs or maintenance issues along the way (there's only one place we read or write the data)

    Next, any methods which need to interact with the student needs to accept an instance of the Student POJO, for example...

    protected void editStuGrade(Student student) throws IOException {
        //...
    }
    

    Then the rest of the code simply comes down to getting information from the user and feeding it into our workflow...

    public class Main {
    
        private Scanner command = new Scanner(System.in);
    
        public static void main(String[] args) throws Exception {
            new Main();
        }
    
        public Main() {
            System.out.println("Enter a students name: ");
            String commandInput = command.next();
            try {
                Student student = Student.loadByName(commandInput);
                editStuGrade(student);
            } catch (IOException ex) {
                System.out.println("Could not read student record: " + ex.getMessage());
            }
        }
    
        protected void editStuGrade(Student student) throws IOException {
            System.out.println("Would you like to edit or quit (edit | quit)?");
            String editInput = command.next();
            if (editInput.equalsIgnoreCase("edit")) {
                // Make some changes...
                student.save();
            } else if (editInput.equalsIgnoreCase("quit")) {
                System.exit(0);
            }
    
        }
    }
    

    Runnable example...

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Scanner;
    import java.util.StringJoiner;
    
    public class Main {
    
        private Scanner command = new Scanner(System.in);
    
        public static void main(String[] args) throws Exception {
            new Main();
        }
    
        public Main() {
            System.out.println("Enter a students name: ");
            String commandInput = command.next();
            try {
                Student student = Student.loadByName(commandInput);
                editStuGrade(student);
            } catch (IOException ex) {
                System.out.println("Could not read student record: " + ex.getMessage());
            }
        }
    
        protected void editStuGrade(Student student) throws IOException {
            System.out.println("Would you like to edit or quit (edit | quit)?");
            String editInput = command.next();
            if (editInput.equalsIgnoreCase("edit")) {
                // Make some changes...
                student.save();
            } else if (editInput.equalsIgnoreCase("quit")) {
                System.exit(0);
            }
    
        }
    
        public static class Student {
    
            private String name;
            private String id;
            private int q1Score;
            private int q2Score;
            private int q3Score;
            private int midTermScore;
            private int finalScore;
    
            public Student(String name, String id, int q1Score, int q2Score, int q3Score, int midTermScore, int finalScore) {
                this.name = name;
                this.id = id;
                this.q1Score = q1Score;
                this.q2Score = q2Score;
                this.q3Score = q3Score;
                this.midTermScore = midTermScore;
                this.finalScore = finalScore;
            }
    
            public static Student loadByName(String name) throws IOException {
                File file = new File(name + ".txt");
                if (!file.exists()) {
                    throw new FileNotFoundException("No record exists for " + name);
                }
    
                try (Scanner input = new Scanner(file)) {
                    input.useDelimiter(",");
                    name = input.next();
                    String id = input.next();
                    int q1Score = input.nextInt();
                    int q2Score = input.nextInt();
                    int q3Score = input.nextInt();
                    int midTermScore = input.nextInt();
                    int finalScore = input.nextInt();
    
                    return new Student(name, id, q1Score, q2Score, q3Score, midTermScore, finalScore);
                }
            }
    
            public void save() throws IOException {
                File file = new File(getName() + ".txt");
                StringJoiner joiner = new StringJoiner(",");
                joiner.add(getName());
                joiner.add(getId());
                joiner.add(Integer.toString(getQ1Score()));
                joiner.add(Integer.toString(getQ2Score()));
                joiner.add(Integer.toString(getQ3Score()));
                joiner.add(Integer.toString(getMidTermScore()));
                joiner.add(Integer.toString(getFinalScore()));
    
                try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
                    bw.write(joiner.toString());
                }
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getId() {
                return id;
            }
    
            public void setId(String id) {
                this.id = id;
            }
    
            public int getQ1Score() {
                return q1Score;
            }
    
            public void setQ1Score(int q1Score) {
                this.q1Score = q1Score;
            }
    
            public int getQ2Score() {
                return q2Score;
            }
    
            public void setQ2Score(int q2Score) {
                this.q2Score = q2Score;
            }
    
            public int getQ3Score() {
                return q3Score;
            }
    
            public void setQ3Score(int q3Score) {
                this.q3Score = q3Score;
            }
    
            public int getMidTermScore() {
                return midTermScore;
            }
    
            public void setMidTermScore(int midTermScore) {
                this.midTermScore = midTermScore;
            }
    
            public int getFinalScore() {
                return finalScore;
            }
    
            public void setFinalScore(int finalScore) {
                this.finalScore = finalScore;
            }
    
        }
    }