【问题标题】:Deleting a specific line from a delimited text file by using user input. (Java)使用用户输入从分隔文本文件中删除特定行。 (爪哇)
【发布时间】:2017-02-28 07:34:43
【问题描述】:

这是我当前的代码:

import java.util.*;
import java.io.*;

public class Adding_Deleting_Car extends Admin_Menu {

        public void delCar() throws IOException{
        Scanner in = new Scanner(System.in);
        File inputFile = new File("inventory.txt");
        File tempFile = new File("myTemp.txt");

        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));

        String currentLine;

        String lineToRemove;
        System.out.println("Enter the VIN of the car you wish to delete/update: ");
        lineToRemove = in.next();

        while((currentLine = reader.readLine()) != null) {
            String trimmedLine = currentLine.trim();
            if(trimmedLine.equals(lineToRemove)) continue;
            System.out.println(trimmedLine);
            writer.write((currentLine) + System.getProperty("line.separator"));
        }
        writer.close();
        reader.close();
        boolean successful = tempFile.renameTo(inputFile);
        System.out.println(successful);
    }
}

我想根据用户输入从文件中删除某行文本。例如,这是我的文本文件:

AB234KXAZ;Honda;Accord;1999;10000;3000;G

AB234KL34;Honda;Civic;2009;15000;4000;R

CD555SA72;Toyota;Camry;2010;11000;7000;S

FF2HHKL94;BMW;535i;2011;12000;9000;W

XX55JKA31;Ford;F150;2015;50000;5000;B

我希望用户输入他们选择的字符串,这将是列中的第一个字段(例如 XX55JKA31),然后从文件中删除该行文本。我在网上找到了一些代码,但一直无法成功使用。

我当前的代码似乎只是重写了临时文本文件中的所有内容,但没有删除它。

【问题讨论】:

  • "我当前的代码似乎只是重写了临时文本文件中的所有内容,但没有删除它。"那么这条线在做什么tempFile.renameTo(inputFile)
  • @Patrick Parker 它返回 false,但我不太确定我应该期待什么,因为我在别处得到了代码。临时文件只是重新创建我的原始文件,而不删除我想要的行。

标签: java text io


【解决方案1】:

您正在使用 File.renameTo,此处记录了该文件: https://docs.oracle.com/javase/8/docs/api/java/io/File.html#renameTo-java.io.File-

根据文档,如果文件已经存在,它可能会失败,你应该使用 Files.move 来代替。

这是 Files.move 的等效代码:

boolean successful;
try {
    Files.move(tempFile.toPath(), inputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    successful = true;
} catch(IOException e) {
    successful = false;
}

注意: 您搜索 VIN 的代码也是错误的。有关该问题的一种可能解决方案,请参阅 Jure Kolenko 的回答。

今后,您应该考虑使用实际的数据库来存储和操作此类信息。

【讨论】:

  • 感谢您的帮助!你的建议奏效了,但我遇到了一个小问题,我必须自己解决。这只是练习,因为我是初学者,但我一定会在未来研究一个实际的数据库。
【解决方案2】:

你的错误在于

if(trimmedLine.equals(lineToRemove)) continue;

它将整行与您要删除的 VIN 进行比较,而不仅仅是第一部分。把它改成

if(trimmedLine.startsWith(lineToRemove)) continue;

它有效。如果您想与不同的列进行比较,请改用String::contains。也像帕特里克帕克所说,使用 Files.move 而不是 File::renameTo 修复了重命名问题。

完整的固定代码:

import java.util.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;



public class Adding_Deleting_Car{

        public static void main(String... args) throws IOException{
        Scanner in = new Scanner(System.in);
        File inputFile = new File("inventory.txt");
        File tempFile = new File("myTemp.txt");

        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));

        String currentLine;

        String lineToRemove;
        System.out.println("Enter the VIN of the car you wish to delete/update: ");
        lineToRemove = in.next();

        while((currentLine = reader.readLine()) != null) {
            String trimmedLine = currentLine.trim();
            if(trimmedLine.startsWith(lineToRemove)) continue;
            System.out.println(trimmedLine);
            writer.write((currentLine) + System.getProperty("line.separator"));
        }
        writer.close();
        reader.close();
        Files.move(tempFile.toPath(), inputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }
}

请注意,我将类定义更改为不继承,并将方法定义更改为 main(String... args),因此我可以在我的系统上编译。

【讨论】:

  • 这在查看临时文件时有效,但由于出现错误,原始文件无法更新:Exception in thread "main" java.nio.file.FileSystemException: inventory.txt: The process cannot access the file because it is being used by another process.
  • 这似乎表明该文件正在被另一个进程使用。尝试关闭任何可能正在使用该文件的应用程序或重新启动系统。
  • 我真的不知道。可能是因为文件可以在另一个类中更新吗?如果我制作另一个文本文件,它会起作用,但我想这意味着我的更新类必须创建某种副本才能让这个 Delete_Car 类工作。嗯...
  • 文件可能也在另一个类中被操作。小心使用文件关闭任何资源。如果你想要一个简单易用的轻量级数据库,你可以使用 SQLite。
  • 你是对的!在我使用它的另一个班级中,它没有正确关闭。谢谢!我肯定会很快研究 SQL。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 1970-01-01
  • 2011-01-07
相关资源
最近更新 更多