满足等于条件时,如何在不丢失文本文件中其他行的情况下替换行?

How to replace line without loosing other lines in text file when equals condition is met?

我有一个包含客户数据、ID、姓名和姓氏、余额和日期的文本文件,一个客户在文本文件中有 4 行,然后有一个 space 和另一个客户数据开始等等.

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

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

我需要为特定客户 ID 块创建行替换,以避免在不使用 ID 的情况下为其他人替换同一行。

我尝试实现一个想法,当代码找到我需要的 ID 时,它会停在那里,跳转,例如,向下一行并编辑该行,但相反,我丢失了除我正在替换的行之外的所有其他行.

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


您遇到困难的原因有很多,这里有一些:

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

正如您在上面的一小段代码中看到的那样,您有效地采用了刚刚读入的行,然后直接应用于将写入文件的字符串。这里的数据没有变化。应该是:

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

这又打开了另一个蠕虫罐头。如果提供的原始名称与提供的 ID 号不匹配怎么办。可能输入错误。在更新文件中的特定项目之前,将其与 toUpdate 参数中包含的内容进行比较:

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

下一行让我很困惑:

input = input.replace(toUpdate, updated);

您确实意识到 input 字符串变量最终将保存文件中包含的所有数据。如果您要更新的项目位于多个不同 ID 号下的多个位置怎么办?上面的行将改变所有这些。摆脱这一行可怕的代码。如果有的话,它应该只应用于 line 变量(当前读入的文件行)。

下面我发布了您的 updateLine() 方法的修改版本。此版本允许您更改任何客户端字段 除了 ID 字段,例如:

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