Как я могу распечатать все между двумя пустыми строками из файла на Java?

#java #bufferedreader #filereader

#java #bufferedreader #filereader

Вопрос:

Итак, я создаю приложение, в котором я сохранял сведения о клиенте, такие как имя, фамилия, DOB, ID и адрес, в файл с именем «clientListFile.txt «. Каждый раз, когда информация о клиенте добавляется в файл, перед и после информации остается пустое пространство, как показано ниже:

     //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)
  

В приведенном ниже коде я могу определить, сохранена ли строка в файле. Например, в моей программе, если я ищу «fn» или если я ищу «1234», он выводит, в какой строке он находится. Однако я хочу, чтобы он распечатал все в JTextArea с именем «jDisplaySearchedClientsTextArea» между первыми двумя пустыми строками и последними двумя пустыми строками.

     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");
        
    }
  
    
}
  

Комментарии:

1. Вы изложили свои требования. Теперь, в чем ваш вопрос? Что мешает вам реализовать эту функциональность? Вы могли бы, например, сохранить все строки одной записи в список во время итерации по нему, сбрасывать список всякий раз, когда вы передаете 2 пустые строки, чтобы начать новую запись, а затем распечатать список, если вы нашли совпадение в записи.

2. Спасибо за ваш ответ. Проблема в том, что я не знаю, как реализовать или как написать этот код. У меня есть ряд идей, включая вашу, но я даже не знаю, с чего начать.

3. Одной из возможностей было бы прочитать весь входной файл в список экземпляров клиента, где класс Client содержит всю информацию о клиенте, использовать список для отображения клиентов в вашем графическом интерфейсе и записать весь список, когда приложение завершится.

4. 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. Вы указываете логику того, что вы хотите сделать. Теперь вам нужно реализовать эту логику в коде. Вам нужно проверить наличие пустой строки, затем, когда строка не пуста, распечатайте вашу информацию, затем, если есть еще одна пустая строка, выйдите из цикла.

Ответ №1:

Вы можете использовать метод, подобный этому:

 /**
 * 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() amp;amp; fieldsCounter == 0) {
                inRecord = true;
            }
            else if (inRecord amp;amp; 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;
}
  

Гораздо лучше, конечно, использовать базу данных для такого рода вещей и использовать клиентский класс. Даже при использовании метода хранения данных типа файла (например, используемого вами), вам действительно хотелось бы, чтобы клиентский класс сохранял эти данные организованными и сохранял данные, больше похожие на файл в стиле CSV (с разделенными файлами). Вот пример пользовательского файла данных CSV:

 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,       his-email@yahoo.com,         604-776-1121      
1235,       Wilma,       Flinstone, 1964-11-30,     2977 Oriole Cooky Way,   Bedrock,       Stones Throw,      V2Q5W8,        Canada,       her-email@yahoo.com,         604-776-3466      
1236,       Jack,        Naso,      1993-03-18,     33912 CrackShack Ave,    Vancouver,     British Columbia,  V2Z1D2,        Canada,       myemailaddy@hotmail.com,     856-302-1122      
1237,       William,     Shakaconn, 1996-12-13,     1212 Playwrite Street,   Langely,       British Columbia,  V2T4C9,        Canada,       playme@gmail.ca,             777-664-9351      
  

В этом пользовательском CSV-файле данные больше похожи на таблицу, а записи более разборчивы даже при простом чтении самого файла. Если вы хотите, чтобы ваш клиентский класс выполнял подобные действия, просто напишите мне.