【问题标题】:Delete Line with BufferedReader使用 BufferedReader 删除行
【发布时间】:2014-06-27 03:52:45
【问题描述】:

我目前正在使用此代码从我的计算机中读取一个 .txt 文件:

BufferedReader in = new BufferedReader(new FileReader("./Data/text.txt"));
String data = null;
try {
    while ((data = in.readLine()) != null) {
        String[] args = data.split(":");

        if (args[1] == "yes")) {
            file.add(data);
        } else {
            //Remove line here  
        }
    }
} finally {
    in.close();
}

现在,对于我阅读的每一行,我都会做一个简单的 if 检查,如果答案不是“是”,我想删除该行并继续下一行。

这可能吗?还是只能读不改?

【问题讨论】:

  • 你正在使用Reader类,所以你不能这样做。

标签: java bufferedreader filereader


【解决方案1】:

如前所述,您可以阅读所有行并跳过不需要的行,之后您可以将其余行存储在同一个文件中。

    List<String> file = new ArrayList();

    BufferedReader in = new BufferedReader(new FileReader("./Data/text.txt"));
    String data = null;
    try {
        while ((data = in.readLine()) != null) {
            String[] args = data.split(":");

            if (args[1].equals("yes")) {
                file.add(data);
            } else {
                //skip this line
            }
        }
        in.close();

        //Add to file
        FileWriter fw = new FileWriter("./Data/text.txt");
        BufferedWriter out = new BufferedWriter(fw);
        for (String line : file) {
            out.write(line + "\n");
        }
        out.flush();
        out.close();

    } catch (Exception e){

    }

您也可以使用Apache Commons IO

    File file = new File("./Data/text.txt");
    List<String> lines = org.apache.commons.io.FileUtils.readLines(file)

    for (int i = 0; i < lines.size(); i++) 
        if (! lines.get(i).split(":")[1].equals("yes")) 
            lines.remove(i--);

    org.apache.commons.io.FileUtils.writeLines(file, lines);

你必须非常小心arg[1],如果你有一个空行,结果将是一个ArrayIndexOutOfBoundsException

附录

我想发布另一种使用 Java 8 lambda 表达式和 Java 7 java.nio.file.* 包的方式。

    List<String> lines = Files.readAllLines(Paths.get("./Data/text.txt"), Charset.defaultCharset());

    Predicate<String> filter = line -> line.split(":")[1].equals("./Data/text.txt");

    String output = lines
            .stream()
            .filter(filter)
            .map(l -> l + "\n")
            .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
            .toString();

    Files.write(Paths.get("test"), output.getBytes());

【讨论】:

  • 您可能希望在换行符中添加回行之间。 ;)
【解决方案2】:

最简单的解决方案是复制您要保留的所有行并将现有文件替换为您刚刚创建的文件。

File orig = new File("Data/text.txt");
File tmp = new File(orig+".tmp");
try (BufferedReader in = new BufferedReader(new FileReader(orig));
     PrintWriter pw = new PrintWriter(new FileWriter(tmp))) {
     for (String data; (data = in.readLine()) != null; )
          if (data.split(":")[1].equals("yes"))
              pw.println(data);
}
if (orig.delete())
    tmp.renameTo(orig);
else
    // cannot delete old file :|

【讨论】:

  • @gia nnischristofakis 好点。假设恰好有一个:,将其更改为匹配问题
  • 对不起,我觉得还是错了。假设该行是adfas:yes:asdfas
  • @giannischristofakis 我确实说过,假设只有一个 :
  • 对不起,我想是renameTo
【解决方案3】:

如果我错了,请纠正我,但您的代码已经“删除”不需要的行(args[1] !=“yes”),为什么?因为你的那个 IF 有这样的声明:

IF 'args[1]' is 'yes' THEN 添加到 'file' 否则什么都不做

也就是说,除了yes,它不会被添加到file,你应该检查file的内容(我假设它是List&lt;String&gt;类型),但我很确定你的代码已经是正确的了。

或者您可以在 else 块中添加 continue;

【讨论】:

    【解决方案4】:

    您不能从文件中“删除”特定行,但您可以读取这些行、删除不需要的行并用清理后的行覆盖文件内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2017-08-11
      • 2020-10-21
      • 2018-06-18
      • 2015-05-12
      • 2019-01-09
      相关资源
      最近更新 更多