我正在尋找一個小代碼片段,它將在文件中找到一行並刪除該行(不是內容但行),但無法找到。因此,例如我有一個文件如下:在文件中找到一行並將其刪除
MYFILE.TXT:
aaa
bbb
ccc
ddd
需要有這樣的功能:public void removeLine(String lineContent)
,如果我通過 removeLine("bbb")
,我得到的文件是這樣的:
MYFILE.TXT:
aaa
ccc
ddd
我正在尋找一個小代碼片段,它將在文件中找到一行並刪除該行(不是內容但行),但無法找到。因此,例如我有一個文件如下:在文件中找到一行並將其刪除
MYFILE.TXT:
aaa
bbb
ccc
ddd
需要有這樣的功能:public void removeLine(String lineContent)
,如果我通過 removeLine("bbb")
,我得到的文件是這樣的:
MYFILE.TXT:
aaa
ccc
ddd
此解決方案可能不是最佳或漂亮的,但它的工作原理。它逐行讀入輸入文件,將每行寫入臨時輸出文件。每當它遇到一條與你正在尋找的線相匹配的線時,它就會跳過寫出一條線。然後重命名輸出文件。我從示例中省略了錯誤處理,關閉了讀者/作者等。我也假設你正在尋找的行中沒有前導空白或尾隨空白。根據需要更改trim()的代碼,以便找到匹配項。
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);
你想這樣做了以下內容:閱讀
(我不會寫實際的代碼,因爲這看起來像家庭作業,但隨時可以發佈其他問題在您遇到麻煩的特定位上)
現在,如果你只是寫出了代碼,那麼你會得到接受的答案,哈哈! ;) – DaveJohnston 2010-03-10 21:45:31
任何不涉及創建臨時文件的解決方案?一些可以在同一個文件中寫入的soln。 – 2017-08-08 11:03:30
@AniketSinha當然。只要確保已將文件完全讀入數組/緩衝區/字符串並對其進行操作(因爲您可以在讀完所有文件後覆蓋原始文件) – 2017-08-13 03:01:48
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();
}
}
這是我在網上找到的。
如果拋出異常,此代碼將不會關閉文件,你也需要一個最終的陳述。 – DaveJohnston 2010-03-10 21:44:53
爲什麼你在每一行後沖洗?這不是沒有效率嗎? – joeytwiddle 2014-06-02 06:02:18
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!");
}
}
}
這裏是完整的類。在下面的文件中,「somelocation」指的是文件的實際路徑。
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);
}
}
使用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);
這是否工作? – 2015-08-22 15:59:14
在這種情況下整個文件會被讀入內存嗎? – Tim 2015-10-07 02:02:03
@Tim恐怕如此 – 2016-08-04 15:26:09
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");
}
}
這種解決方案需要被添加到構建路徑的Apache Commons IO library。它通過讀取整個文件並將每行寫回,但只有在不包含搜索項時才起作用。
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必須創建(據我)一個稍微更有效,更容易理解的代碼的解決方案。我使用了嵌入式自動資源管理,它是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();
}
所以,每當我聽到有人提到,他們希望過濾掉的文字,我立刻想到去Streams(主要是因爲有一種方法稱爲filter
,它按照您的需要進行過濾)。另一個答案提及使用Stream
s的Apache的公地IO庫,但我認爲這將是值得的,以顯示如何在標準Java 8.這是最簡單的形式來完成:
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);
}
我認爲有ISN這裏沒有太多的解釋,基本上Files.lines
得到Stream<String>
的文件行,filter
拿出我們不想要的行,然後collect
把新文件的所有行放入List
。然後,我們使用附加選項TRUNCATE
在現有文件頂部的Files.write
上編寫列表,以替換文件的舊內容。
當然,這種方法將每一行加載到內存中都是不利的,因爲它們在被寫回前都被存儲到List
中。如果我們想幹脆不保存修改,我們就需要通過流使用某種形式的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
,以便立即寫入到文件中而不存儲。我們必須將它保存到一個臨時文件中,因爲我們無法同時覆蓋現有文件,因爲我們仍然在讀取它,所以最後我們重命名臨時文件以替換現有文件。
您是否找到了實現此目標的最佳方法。更快,更快的方式 – 2016-06-20 12:22:05