在文件中find一行并将其删除

我正在寻找一个小的代码片段,将在文件中find一行,并删除该行(不是内容,但行),但无法find。 所以例如我有一个文件在下面:

myFile.txt

aaa bbb ccc ddd 

需要有这样的function: public void removeLine(String lineContent) ,如果我传递removeLine("bbb") ,我得到这样的文件:

MYFILE.TXT:

 aaa ccc ddd 

这个解决scheme可能不是最佳或漂亮的,但它的工作原理。 它逐行读入input文件,将每行写入临时输出文件。 每当它遇到一条符合你要找的东西的线时,它就会跳过这一条。 然后重命名输出文件。 我从例子中省略了error handling,closures了读者/作者等等。 我也假定你正在寻找的行中没有前导或尾随的空白。 根据需要更改trim()的代码,以便find匹配项。

 File inputFile = new File("myFile.txt"); File tempFile = new File("myTempFile.txt"); BufferedReader reader = new BufferedReader(new FileReader(inputFile)); BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile)); String lineToRemove = "bbb"; String currentLine; while((currentLine = reader.readLine()) != null) { // trim newline when comparing with lineToRemove String trimmedLine = currentLine.trim(); if(trimmedLine.equals(lineToRemove)) continue; writer.write(currentLine + System.getProperty("line.separator")); } writer.close(); reader.close(); boolean successful = tempFile.renameTo(inputFile); 
  public void removeLineFromFile(String file, String lineToRemove) { try { File inFile = new File(file); if (!inFile.isFile()) { System.out.println("Parameter is not an existing file"); return; } //Construct the new file that will later be renamed to the original filename. File tempFile = new File(inFile.getAbsolutePath() + ".tmp"); BufferedReader br = new BufferedReader(new FileReader(file)); PrintWriter pw = new PrintWriter(new FileWriter(tempFile)); String line = null; //Read from the original file and write to the new //unless content matches data to be removed. while ((line = br.readLine()) != null) { if (!line.trim().equals(lineToRemove)) { pw.println(line); pw.flush(); } } pw.close(); br.close(); //Delete the original file if (!inFile.delete()) { System.out.println("Could not delete file"); return; } //Rename the new file to the filename the original file had. if (!tempFile.renameTo(inFile)) System.out.println("Could not rename file"); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } 

这是我在互联网上find的。

你想要做的事情如下:

  • 打开旧文件进行阅读
  • 打开一个新的(临时)文件进行写入
  • 迭代旧文件中的行(可能使用BufferedReader )
    • 对于每一行,检查它是否符合你应该删除
    • 如果匹配,什么都不要做
    • 如果不匹配,请将其写入临时文件
  • 完成后,closures这两个文件
  • 删除旧文件
  • 将临时文件重命名为原始文件的名称

(我不会写实际的代码,因为这看起来像功课,但随意发布其他问题,你有麻烦的特定位)

使用apache commons-io和Java 8,你可以使用

  List<String> lines = FileUtils.readLines(file); List<String> updatedLines = lines.stream().filter(s -> !s.contains(searchString)).collect(Collectors.toList()); FileUtils.writeLines(file, updatedLines, false); 

这是完整的类。 在下面的文件中,“somelocation”是指文件的实际path。

 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FileProcess { public static void main(String[] args) throws IOException { File inputFile = new File("C://somelocation//Demographics.txt"); File tempFile = new File("C://somelocation//Demographics_report.txt"); BufferedReader reader = new BufferedReader(new FileReader(inputFile)); BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile)); String currentLine; while((currentLine = reader.readLine()) != null) { if(null!=currentLine && !currentLine.equalsIgnoreCase("BBB")){ writer.write(currentLine + System.getProperty("line.separator")); } } writer.close(); reader.close(); boolean successful = tempFile.renameTo(inputFile); System.out.println(successful); } } 

所以,每当我听到有人提到他们想要过滤掉文本时,我立刻想到了Streams (主要是因为有一种方法叫做filter ,它完全按照你的需要进行过滤)。 另一个答案提到使用Stream与Apache commons-io库,但我认为这是值得的,以显示如何在标准的Java 8中完成。这是最简单的forms:

 public void removeLine(String lineContent) throws IOException { File file = new File("myFile.txt"); List<String> out = Files.lines(file.toPath()) .filter(line -> !line.contains(lineContent)) .collect(Collectors.toList()); Files.write(file.toPath(), out, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); } 

我觉得这里没有太多的解释,基本上Files.lines得到一个Stream<String>的文件行, filter取出我们不想要的行,然后collect所有行的新文件到List 。 然后,我们用Files.write在现有文件的顶部写入列表,使用额外的选项TRUNCATE ,以replace文件的旧内容。

当然,这种方法的缺点是将每行加载到内存中,因为它们都被存储到List然后被写回。 如果我们只是简单地修改而不存储,那么我们需要使用某种forms的OutputStream来将每一个新行写入一个文件,如下所示:

 public void removeLine(String lineContent) throws IOException { File file = new File("myFile.txt"); File temp = new File("_temp_"); PrintWriter out = new PrintWriter(new FileWriter(temp)); Files.lines(file.toPath()) .filter(line -> !line.contains(lineContent)) .forEach(out::println); out.flush(); out.close(); temp.renameTo(file); } 

在这个例子中没有太多改变。 基本上,我们不使用collect将文件内容收集到内存中,而是使用forEach ,使得每行通过filter行都被发送到PrintWriter以立即写入文件,而不是存储。 我们必须把它保存到一个临时文件中,因为我们不能同时覆盖现有的文件,所以最后我们重命名临时文件来replace现有的文件。

 public static void deleteLine(String line, String filePath) { File file = new File(filePath); File file2 = new File(file.getParent() + "\\temp" + file.getName()); PrintWriter pw = null; Scanner read = null; FileInputStream fis = null; FileOutputStream fos = null; FileChannel src = null; FileChannel dest = null; try { pw = new PrintWriter(file2); read = new Scanner(file); while (read.hasNextLine()) { String currline = read.nextLine(); if (line.equalsIgnoreCase(currline)) { continue; } else { pw.println(currline); } } pw.flush(); fis = new FileInputStream(file2); src = fis.getChannel(); fos = new FileOutputStream(file); dest = fos.getChannel(); dest.transferFrom(src, 0, src.size()); } catch (IOException e) { e.printStackTrace(); } finally { pw.close(); read.close(); try { fis.close(); fos.close(); src.close(); dest.close(); } catch (IOException e) { e.printStackTrace(); } if (file2.delete()) { System.out.println("File is deleted"); } else { System.out.println("Error occured! File: " + file2.getName() + " is not deleted!"); } } } 
 package com.ncs.cache; import java.io.BufferedReader; import java.io.FileReader; import java.io.File; import java.io.FileWriter; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; public class FileUtil { public void removeLineFromFile(String file, String lineToRemove) { try { File inFile = new File(file); if (!inFile.isFile()) { System.out.println("Parameter is not an existing file"); return; } // Construct the new file that will later be renamed to the original // filename. File tempFile = new File(inFile.getAbsolutePath() + ".tmp"); BufferedReader br = new BufferedReader(new FileReader(file)); PrintWriter pw = new PrintWriter(new FileWriter(tempFile)); String line = null; // Read from the original file and write to the new // unless content matches data to be removed. while ((line = br.readLine()) != null) { if (!line.trim().equals(lineToRemove)) { pw.println(line); pw.flush(); } } pw.close(); br.close(); // Delete the original file if (!inFile.delete()) { System.out.println("Could not delete file"); return; } // Rename the new file to the filename the original file had. if (!tempFile.renameTo(inFile)) System.out.println("Could not rename file"); } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } public static void main(String[] args) { FileUtil util = new FileUtil(); util.removeLineFromFile("test.txt", "bbbbb"); } } 

src: http : //www.javadb.com/remove-a-line-from-a-text-file/

该解决scheme需要将Apache Commons IO库添加到构buildpath中。 它的工作原理是读取整个文件并将每行写回,但前提是不包含search项。

 public static void removeLineFromFile(File targetFile, String searchTerm) throws IOException { StringBuffer fileContents = new StringBuffer( FileUtils.readFileToString(targetFile)); String[] fileContentLines = fileContents.toString().split( System.lineSeparator()); emptyFile(targetFile); fileContents = new StringBuffer(); for (int fileContentLinesIndex = 0; fileContentLinesIndex < fileContentLines.length; fileContentLinesIndex++) { if (fileContentLines[fileContentLinesIndex].contains(searchTerm)) { continue; } fileContents.append(fileContentLines[fileContentLinesIndex] + System.lineSeparator()); } FileUtils.writeStringToFile(targetFile, fileContents.toString().trim()); } private static void emptyFile(File targetFile) throws FileNotFoundException, IOException { RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw"); randomAccessFile.setLength(0); randomAccessFile.close(); } 

我重构了Narek必须创build的解决scheme(据我所知),这个解决scheme的效率稍高一些,易于理解。 我使用embedded式自动资源pipe理(Java)中最近的一个特性,并使用了一个Scanner类,根据我的说法,这个类更容易理解和使用。

这里是编辑的评论的代码:

 public class RemoveLineInFile { private static File file; public static void main(String[] args) { //create a new File file = new File("hello.txt"); //takes in String that you want to get rid off removeLineFromFile("Hello"); } public static void removeLineFromFile(String lineToRemove) { //if file does not exist, a file is created if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { System.out.println("File "+file.getName()+" not created successfully"); } } // Construct the new temporary file that will later be renamed to the original // filename. File tempFile = new File(file.getAbsolutePath() + ".tmp"); //Two Embedded Automatic Resource Managers used // to effectivey handle IO Responses try(Scanner scanner = new Scanner(file)) { try (PrintWriter pw = new PrintWriter(new FileWriter(tempFile))) { //a declaration of a String Line Which Will Be assigned Later String line; // Read from the original file and write to the new // unless content matches data to be removed. while (scanner.hasNextLine()) { line = scanner.nextLine(); if (!line.trim().equals(lineToRemove)) { pw.println(line); pw.flush(); } } // Delete the original file if (!file.delete()) { System.out.println("Could not delete file"); return; } // Rename the new file to the filename the original file had. if (!tempFile.renameTo(file)) System.out.println("Could not rename file"); } } catch (IOException e) { System.out.println("IO Exception Occurred"); } } } 

尝试这个:

 public static void main(String[] args) throws IOException { File file = new File("file.csv"); CSVReader csvFileReader = new CSVReader(new FileReader(file)); List<String[]> list = csvFileReader.readAll(); for (int i = 0; i < list.size(); i++) { String[] filter = list.get(i); if (filter[0].equalsIgnoreCase("bbb")) { list.remove(i); } } csvFileReader.close(); CSVWriter csvOutput = new CSVWriter(new FileWriter(file)); csvOutput.writeAll(list); csvOutput.flush(); csvOutput.close(); } 
  public static void deleteLine() throws IOException { RandomAccessFile file = new RandomAccessFile("me.txt", "rw"); String delete; String task=""; byte []tasking; while ((delete = file.readLine()) != null) { if (delete.startsWith("BAD")) { continue; } task+=delete+"\n"; } System.out.println(task); BufferedWriter writer = new BufferedWriter(new FileWriter("me.txt")); writer.write(task); file.close(); writer.close(); }