Search code examples
javabufferedreaderfilereader

How can I print out everything between two empty lines from a file in Java?


So, I am making an application where I saved details of a client such as first name, surname, DOB, ID and address into a file called "clientListFile.txt". Everytime, a client information is added to the file there is an empty space before and after the information as shown below:

    //empty line
    //empty line
    fn
    sn
    1900-08-01
    1234
    addressname
    s
    8
    hn
    a
    pc
    t
    country
    //empty line
    //empty line
    fn1
    sn1
    1900-08-02 ... (etc)

In the code below, I am able to find if a string is stored into the file. For example, in my program, if I search "fn" or if I search "1234", it prints out which line it is located on. However, I want it to print out everything in the JTextArea called "jDisplaySearchedClientsTextArea" between the first two empty lines and the last two empty lines.

    private void jSearchClientsButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                     
    // TODO add your handling code here:
    
    String fn = jClientsFNTextField.getText();
    
    String clientListFile = "clientListFile.txt";

    try {
        
        BufferedReader areader = new BufferedReader(new FileReader(new File(clientListFile)));
        Scanner scanner = new Scanner(clientListFile);

        //now read the file line by line...
        int lineNum = 0;
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            lineNum++;
            if (fn.equals(areader.readLine())) {

                System.out.println("ho hum, i found it on line " +lineNum);

            }
        }
    } 
    catch (IOException ioe) {
        
        System.out.println("Error while saving Head Office Address");
        
    }
  
    
}

Solution

  • You might use a method something like this:

    /**
     * Parses and searches a "clientListFile.txt" data file based on the supplied 
     * search criteria.<br>
     * 
     * @param dataFilePath (String) The full path and file name of the data file 
     * to search in.<br>
     * 
     * @param searchCriteria (String) What to search for in each data record 
     * contained within the supplied data file.<br>
     * 
     * @param useContains (Optional - Boolean - Default is True) This optional 
     * parameter by default is boolean '<b>true</b>'. This means that every search 
     * done in any data file record is carried out by locating the search criteria 
     * (ignoring letter case) within any record field value location that <u><b>contains</b></u> 
     * the search criteria. An example 
     * of this would be:<pre>
     * 
     *      Search Criteria:  "fred"
     * 
     *      A Data Record:
     *      =============
     *      First Name: Danny           (No Match)
     *      Surname:    Fredrikson      (Match - Fred......)
     *      Birthdate:  1957-11-07      (No Match)
     *      Cient ID:   1234            (No Match)
     *      Address:    3233 Sandy St.  (No Match)
     *      City:       Fredericton     (Match - Fred.......)
     *      Province:   New Brunswick   (No Match)
     *      etc.....</pre><br>
     * 
     * If boolean '<b>false</b>' is optionally supplied then the search is done 
     * based on <u><b>equality</b></u>. This means that every search done in any data file 
     * record is carried out by locating the search criteria within any record 
     * field value that is <b>equal to</b> (ignoring letter case) the supplied 
     * search criteria. An example of this would be:<pre>
     * 
     *      Search Criteria:  "fred"
     * 
     *      A Data Record:
     *      =============
     *      First Name: Fred            (Match - Fred)
     *      Surname:    Fredrikson      (No Match)
     *      Birthdate:  1957-11-07      (No Match)
     *      Cient ID:   1234            (No Match)
     *      Address:    3233 Sandy St.  (No Match)
     *      City:       Fredericton     (No Match)
     *      Province:   New Brunswick   (No Match)
     *      etc.....</pre><br>
     * 
     * @return  A List Interface Object of Type String - {@code List<String>}.
     */
    public static List<String> searchInRecords(String dataFilePath, String searchCriteria, boolean... useContains) {
        boolean UseCONTAINSinSearches = true;
        if (useContains.length > 0) {
            UseCONTAINSinSearches = useContains[0];
        }
        int fileLinesCounter = 0;
        int fieldsCounter = 0;
        int dataRecordsCounter = 0;
        int criterialFoundRecords = 0;
        boolean inRecord = false;
    
        List<String> foundRecords = new ArrayList<>();
    
        String[] fields = new String[12];
    
        // 'Try With Resources' use here to auto-close the reader.
        try (BufferedReader reader = new BufferedReader(new FileReader(dataFilePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                fileLinesCounter++;
                line = line.trim();
                if (line.isEmpty() && fieldsCounter == 0) {
                    inRecord = true;
                }
                else if (inRecord && fieldsCounter <= 11) {
                    fields[fieldsCounter] = line;
                    if (fieldsCounter == 11) {
                        String record = new StringBuilder("").append(fields[0]).append(", ")
                                .append(fields[1]).append(", ").append(fields[2]).append(", ")
                                .append(fields[3]).append(", ").append(fields[4]).append(", ")
                                .append(fields[5]).append(", ").append(fields[6]).append(", ")
                                .append(fields[7]).append(", ").append(fields[8]).append(", ")
                                .append(fields[9]).append(", ").append(fields[10]).append(", ")
                                .append(fields[11]).toString();
                        dataRecordsCounter++;
                        // Search Type 1 (using CONTAINS where criteria is anywhere in a field)
                        if (UseCONTAINSinSearches) {
                            for (String field : fields) {
                                if (field == null) { continue; }
                                if (field.toLowerCase().contains(searchCriteria)) {
                                    if (!foundRecords.contains(record)) {
                                        foundRecords.add(record);
                                        criterialFoundRecords++;
                                    }
                                }
                            }
                        }
                        // Search Type 2 (using exact match to field but ignoring letter case)
                        else {
                            for (String field : fields) {
                                if (field == null) { continue; }
                                if (field.equalsIgnoreCase(searchCriteria)) {
                                    if (!foundRecords.contains(record)) {
                                        foundRecords.add(record);
                                        criterialFoundRecords++;
                                    }
                                }
                            }
                        }
                    }
                    fieldsCounter++;
                }
                else {
                    fieldsCounter = 0;
                    inRecord = false;
                }
            }
        }
        // Handle the exceptions (if any) any way you see fit.
        catch (FileNotFoundException ex) {
            System.err.println(ex);
        }
        catch (IOException ex) {
            System.err.println(ex);
        }
        
        /* The following integer type variables can be used to supply related
           class member variables. They serve no specific purpose within this
           method and can be removed if desired. Sometimes this information can 
           be handy.       */
        System.out.println("Overall Number of Data File Lines: --> " + fileLinesCounter);
        System.out.println("Overall Number of Records in File: --> " + dataRecordsCounter);
        System.out.println("Criterial Search  - Records Found: --> " + criterialFoundRecords);
        
        return foundRecords;
    }
    

    Far better of course to utilize a database for this sort of thing and the use of a Client class. Even with a file type data storage method (like you are using), you would really want a Client class to keep that data organized and store the data more like in a CSV style (Comma Separated Values) file. Here is an example of a custom CSV data file:

    Client ID,  First Name,  Sir Name,  Date Of Birth,  Address,                 City,          State/Province,    Postal Code,   Country,      E-Mail,                      Phone Number
    =======================================================================================================================================================================================
    1234,       Fred,        Flinstone, 1957-11-07,     2977 Oriole Cooky Way,   Bedrock,       Stones Throw,      V2Q5W8,        Canada,       [email protected],         604-776-1121      
    1235,       Wilma,       Flinstone, 1964-11-30,     2977 Oriole Cooky Way,   Bedrock,       Stones Throw,      V2Q5W8,        Canada,       [email protected],         604-776-3466      
    1236,       Jack,        Naso,      1993-03-18,     33912 CrackShack Ave,    Vancouver,     British Columbia,  V2Z1D2,        Canada,       [email protected],     856-302-1122      
    1237,       William,     Shakaconn, 1996-12-13,     1212 Playwrite Street,   Langely,       British Columbia,  V2T4C9,        Canada,       [email protected],             777-664-9351      
    

    In this custom CSV file the data is laid out more like a table and records are more legible even when just reading the file itself. If you want your Client class to do this sort of thing then just E-Mail me.