Search code examples
javaarraylistcollectionsbufferedreaderbufferedwriter

Find a specific line in a file, write that line and the 2 after to a new file


I need to search for a specific line in a .txt file like someones name and then write the name and the next 2 lines after which is data about the person to a new file.

How it should work: I enter a menu which lists employees taken from an arraylist and asks for my input for who I want a "report" for. I enter "John Doe" and the program creates a "report" called "JDoe.txt" and searches the arraylist for "John Doe" and writes his name in the new file along with his information (the next 2 lines after his name in the same file).

My code is creating the "report" and is writing data to it, but it just writing the data of what is first in the arraylist and not specifically the user who I entered. How do I write for the specific user I inputted?

Here is some of the code I have which is in the right direction but isn't producing what I want and I can't seem to figure out a fix:

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

import javax.swing.JOptionPane;

public class Report { // FirstName LastName, Programmer
    public Report() {
        // code here the logic to create a report for the user
        try {
            String empList = "";
            ArrayList<String> emps = new ArrayList<>();
            String[] firstLine = new String[100], secondLine = new String[100], thirdLine = new String[100];

            int index;

            FileReader file = new FileReader("payroll.txt");
            BufferedReader buffer = new BufferedReader(file);

            String line;

            for (index = 0; index < 100; index++) {
                firstLine[index] = "";
                secondLine[index] = "";
                thirdLine[index] = "";
            }

            index = 0;

            while ((line = buffer.readLine()) != null) {
                firstLine[index] = line;
                secondLine[index] = buffer.readLine();
                thirdLine[index] = buffer.readLine();
                emps.add(firstLine[index]);

                index++;
            }

            buffer.close();

            Collections.sort(emps);
            for (String str : emps) {
                empList += str + "\n";
            }

            String input = JOptionPane.showInputDialog(null, empList,
                    "Employee List", JOptionPane.PLAIN_MESSAGE);

            index = 0;

            // Iterate through the array containing names of employees
            // Check if a match is found with the input got from the user.
            // Break from the loop once you encounter the match.
            // Your index will now point to the data of the matched name

            if (emps.contains(input)) {

                JOptionPane.showMessageDialog(null, "Report Generated.",
                        "Result", JOptionPane.PLAIN_MESSAGE);

                String names[] = new String[2];
                names = input.split(" ");

                String fileName = names[0].charAt(0) + names[1] + ".txt";

                // Create a FileWritter object with the filename variable as the
                // name of the file.
                // Write the necessary data into the text files from the arrays
                // that
                // hold the employee data.
                // Since the index is already pointing to the matched name, it
                // will
                // also point to the data of the matched employee.
                // Just use the index on the appropriate arrays.

                File check1 = new File(fileName);
                FileWriter file2;
                if (check1.exists())
                    file2 = new FileWriter(fileName, true);
                else
                    file2 = new FileWriter(fileName);
                BufferedWriter buffer2 = new BufferedWriter(file2);

                buffer2.write("Name: " + firstLine[index]);
                buffer2.newLine();
                buffer2.write("Hours: " + secondLine[index]);
                buffer2.newLine();
                buffer2.write("Wage: " + thirdLine[index]);
                buffer2.newLine();
                buffer2.close();

            } else {
                JOptionPane.showMessageDialog(null, input + " does not exist");
                Report rpt = new Report();
            }

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        new Report();
    }
}

What the file it is reading from looks like:

payroll.txt


Solution

  • There were two problems I found. The first was that after you when through and built your list of names, you were setting index = 0, and it never got changed.

    for (String str : emps) {
         empList += str + "\n";
    }
    //Make the JOptionPane...
    index = 0;
    

    This meant you were always getting the first value. If you set index to 1, you would get the second value. You can use the method indexOf(Object o) from the ArrayList library to get the correct index given the name that the user input. Example:

    int i = emps.indexOf(input);
    buffer2.write("Name: " + firstline[i]);
    

    However, this would only partly solve the problem, as you sorted the list of employee names in emps, but not in the arrays you are using to write.

    One solution to this is to not sort the emps array, which gives you the correct ordering to indexOf to work properly, but the employees listed in the JOptionPane will be listed in the order they were in the file.

    However, since the values given for each employee are tied to that employee, I would suggest using a data structure that ties those values to the employee name, such as a Map. (Documentation is here: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html ).

    To initialize it, you can use it like this. I'm using a linkedHashMap because it came to my mind, you can select the proper type for your needs.

    LinkedHashMap myMap<String, String[]> = new LinkedHashMap<String, String[]>();
    

    The first field, String is your Key, which will be your employees name. The Value is the String[], and can be an array with the required two values. This ties these values to the name, ensuring they cannot get lost. To check for a name, just use myMap.containsKey(name), and compare to null to see if it exists, and then use myMap.get(name) to get the entry for that name.