Как заменить строку без потери других строк в текстовом файле при выполнении условия равенства? - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть текстовый файл, содержащий данные клиента, идентификатор, имя и фамилию, баланс и дату, 4 строки для одного клиента в текстовом файле, затем есть пробел, и начинаются данные другого клиента и так далее.

ID:33
Client: Michael Reedus
Balance: 30000 Eur
Date: 32.03.2019

ID:34
Client: Michael Snow
Balance: 31900 Eur
Date: 32.03.2019

Мне нужно создать замену строки для определенного блока идентификатора клиента, чтобы избежать замены этой же строки другим человеком без использования идентификатора.

Я попытался реализовать идею, когда код находит идентификаторчто мне нужно, он останавливается на этом, переходит, например, на строку ниже и редактирует эту строку, но вместо этого я теряю все остальные строки, кроме строки, которую я заменяю.

private static void updateLine(String fails, String ID, String toUpdate, String updated) throws IOException {
        BufferedReader file = new BufferedReader(new FileReader(fails));
        String line;
        String input = "";

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

            if (line.equals(ID)) {

                line = file.readLine();
                input += line + System.lineSeparator();

                input = input.replace(toUpdate, updated);
            }

        }

        FileOutputStream os = new FileOutputStream(fails);
        os.write(input.getBytes());

        file.close();
        os.close();
    }

Я ожидаю получить

ID:33
Client: Michael Jordan
Balance: 30000 Eur
Date: 32.03.2019

не


Client: Michael Jordan


1 Ответ

1 голос
/ 02 апреля 2019

Есть ряд причин, по которым у вас возникли трудности, вот некоторые из них:

if (line.equals(ID)) {
    line = file.readLine();
    input += line + System.lineSeparator();

Как вы можете видеть в приведенном выше фрагменте кода, вы фактически берете строку, которую только что прочитали, и затем применяете непосредственно к вашей строке, которая будет записана в файл. Там нет никаких изменений в данных здесь. Должно быть:

if (line.equals(ID)) {
    line = file.readLine();
    input += updated + System.lineSeparator();

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

if (line.equals(ID)) {
    line = file.readLine();
    if (line.equals(toUpdate)) {
        input += updated + System.lineSeparator();
    }

Эта следующая строка действительно озадачивает меня:

input = input.replace(toUpdate, updated);

Вы понимаете, что строковая переменная input в конечном итоге будет содержать ВСЕ данные, содержащиеся в вашем файле. Что если элемент, который вы хотите обновить, находится в нескольких местах под разными идентификационными номерами? Строка выше изменит их все. Избавьтесь от этой страшной строки кода. Во всяком случае, его следует применять только к переменной line (строка файла, которая в данный момент читается).

Ниже я разместил измененную версию вашего updateLine () . Эта версия позволяет изменить любое поле клиента , кроме поля идентификатора, например:

updateLine("clients.txt", "ID:33", "Date: 32.03.2019", "Date: 31.03.2019");

updateLine("clients.txt", "ID:34", "Client: Michael Snow", "Client: John Smith");

updateLine("clients.txt", "ID:34", "Balance: 31900", "Balance: 1253672");

Вот код (большая часть комментариев):

private static void updateLine(String fails, String ID, String toUpdate, String updated) {
    // Try With Resources is used to autoclose the BufferedReader
    try (BufferedReader file = new BufferedReader(new FileReader(fails))) {
        String line;
        String input = "";
        while ((line = file.readLine()) != null) {
            if (line.equals(ID)) {
                // Append the ID to String
                input+= ID + System.lineSeparator(); 
                /* Loop through this client's data and make 
                   changes where necessary...   */
                while ((line = file.readLine()) != null) {
                    /* If we get to this point where we read an ID again
                       then we've gone too far. The item to update could
                       not be found under the supplied ID Number.  */
                    if (line.startsWith("ID:")) {
                        // Append the original ID to String.
                        System.out.println("The item to update (" + toUpdate + 
                                ") could not be found under the ID of: " + ID);
                        // Add this line to string anyways.
                        input+= line + System.lineSeparator();
                        break; // Break out of this inner lop
                    }
                    // Does file line match the supplied toUpdate?
                    if (line.equals(toUpdate)) {
                        // Yes - Append the new item to String
                        input+= updated + System.lineSeparator();
                        break; // Get out of inner loop. Let main loop take over again.
                    }
                    else {
                        // Append the original item to String.
                        input+= line + System.lineSeparator();
                    }
                }
            }
            else {
                input+= line + System.lineSeparator();
            }
        }   
        // Re-Write File with new data
        // Try With Resources is used to autoclose the Stream
        try (FileOutputStream os = new FileOutputStream(fails)) {
            os.write(input.getBytes());
            os.flush();
        }
    }
    catch (FileNotFoundException ex) {
        ex.printStackTrace();
    }
    catch (IOException ex) {
        ex.printStackTrace();
    }
}
...