我正在寻找一个小代码片段,它会在文件中找到一行并删除该行(不是内容而是行)但找不到。例如,我在以下文件中有:
MYFILE.TXT :
aaa
bbb
ccc
ddd
需要有这样的功能:public void removeLine(String lineContent)
,如果我通过
removeLine("bbb")
,我得到这样的文件:
MYFILE.TXT:
aaa
ccc
ddd
答案 0 :(得分:75)
此解决方案可能不是最佳或漂亮,但它可行。它逐行读入输入文件,将每一行写入临时输出文件。每当遇到符合您要求的行时,它就会跳过写出来的那一行。然后重命名输出文件。我从示例中省略了错误处理,关闭读者/编写者等。我还假设您正在寻找的行中没有前导或尾随空格。根据需要更改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);
答案 1 :(得分:24)
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();
}
}
我在互联网上找到了这个。
答案 2 :(得分:20)
您想要执行以下操作:
(我不会写实际代码,因为这看起来像是家庭作业,但随时可以发布有关您遇到问题的特定位的其他问题)
答案 3 :(得分:16)
使用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);
答案 4 :(得分:9)
所以,每当我听到有人提到他们想要过滤掉文字时,我会立即想到Streams(主要是因为有一个名为filter
的方法可以根据需要过滤)。另一个答案提到在Apache commons-io库中使用Stream
,但我认为在标准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);
}
我认为在那里解释不是太多,基本上Files.lines
得到文件的Stream<String>
行,filter
取出我们不会接受的行&#39} ; t想要,然后collect
将新文件的所有行放入List
。然后,我们使用附加选项Files.write
在TRUNCATE
的现有文件顶部写下列表,以便替换该文件的旧内容。
当然,这种方法的缺点是将每一行加载到内存中,因为它们在被写回之前都存储在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
立即写入文件而不存储。我们必须将它保存到临时文件中,因为我们无法在读取现有文件的同时覆盖现有文件,因此最后,我们重命名临时文件以替换现有文件。
答案 5 :(得分:2)
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();
}
答案 6 :(得分:2)
您在这里。此解决方案使用DataInputStream
扫描要替换的字符串的位置,并使用FileChannel
替换该确切位置的文本。它仅替换找到的字符串的第一个匹配项。此解决方案不会将整个文件的副本存储在某个地方(RAM或临时文件),它只会编辑找到的文件部分。
public static long scanForString(String text, File file) throws IOException {
if (text.isEmpty())
return file.exists() ? 0 : -1;
// First of all, get a byte array off of this string:
byte[] bytes = text.getBytes(/* StandardCharsets.your_charset */);
// Next, search the file for the byte array.
try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
List<Integer> matches = new LinkedList<>();
for (long pos = 0; pos < file.length(); pos++) {
byte bite = dis.readByte();
for (int i = 0; i < matches.size(); i++) {
Integer m = matches.get(i);
if (bytes[m] != bite)
matches.remove(i--);
else if (++m == bytes.length)
return pos - m + 1;
else
matches.set(i, m);
}
if (bytes[0] == bite)
matches.add(1);
}
}
return -1;
}
public static void replaceText(String text, String replacement, File file) throws IOException {
// Open a FileChannel with writing ability. You don't really need the read
// ability for this specific case, but there it is in case you need it for
// something else.
try (FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.READ)) {
long scanForString = scanForString(text, file);
if (scanForString == -1) {
System.out.println("String not found.");
return;
}
channel.position(scanForString);
channel.write(ByteBuffer.wrap(replacement.getBytes(/* StandardCharsets.your_charset */)));
}
}
输入:ABCDEFGHIJKLMNOPQRSTUVWXYZ
方法调用:
replaceText("QRS", "000", new File("path/to/file");
结果文件:ABCDEFGHIJKLMNOP000TUVWXYZ
答案 7 :(得分:1)
这是完整的课程。在下面的文件&#34; somelocation&#34;指的是文件的实际路径。
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);
}
}
答案 8 :(得分:0)
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!");
}
}
}
答案 9 :(得分:0)
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");
}
}
答案 10 :(得分:0)
此解决方案需要将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();
}
答案 11 :(得分:0)
我重构了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");
}
}
}
答案 12 :(得分:0)
试试这个:
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();
}
答案 13 :(得分:0)
古老的问题,但是一个简单的方法是:
答案 14 :(得分:0)
此解决方案使用RandomAccessFile
仅缓存要删除的字符串之后的文件部分。扫描直到找到要删除的String
。然后,它将所有数据复制到找到的字符串之后 ,然后将其写入找到的字符串,以及之后的所有内容。最后,它会截断文件大小以删除多余的数据。
public static long scanForString(String text, File file) throws IOException {
if (text.isEmpty())
return file.exists() ? 0 : -1;
// First of all, get a byte array off of this string:
byte[] bytes = text.getBytes(/* StandardCharsets.your_charset */);
// Next, search the file for the byte array.
try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
List<Integer> matches = new LinkedList<>();
for (long pos = 0; pos < file.length(); pos++) {
byte bite = dis.readByte();
for (int i = 0; i < matches.size(); i++) {
Integer m = matches.get(i);
if (bytes[m] != bite)
matches.remove(i--);
else if (++m == bytes.length)
return pos - m + 1;
else
matches.set(i, m);
}
if (bytes[0] == bite)
matches.add(1);
}
}
return -1;
}
public static void remove(String text, File file) throws IOException {
try (RandomAccessFile rafile = new RandomAccessFile(file, "rw");) {
long scanForString = scanForString(text, file);
if (scanForString == -1) {
System.out.println("String not found.");
return;
}
long remainderStartPos = scanForString + text.getBytes().length;
rafile.seek(remainderStartPos);
int remainderSize = (int) (rafile.length() - rafile.getFilePointer());
byte[] bytes = new byte[remainderSize];
rafile.read(bytes);
rafile.seek(scanForString);
rafile.write(bytes);
rafile.setLength(rafile.length() - (text.length()));
}
}
文件内容:ABCDEFGHIJKLMNOPQRSTUVWXYZ
方法调用:remove("ABC", new File("Drive:/Path/File.extension"));
结果内容:DEFGHIJKLMNOPQRSTUVWXYZ
如果需要考虑内存问题,可以很容易地修改此解决方案以使用特定的cacheSize
删除。这仅涉及遍历文件的其余部分以连续替换大小cacheSize
的部分。无论如何,该解决方案通常比在内存中缓存整个文件或将其复制到临时目录等要好得多。
答案 15 :(得分:0)
此解决方案逐行读取输入文件,并将每一行写到StringBuilder变量中。每当遇到与您要查找的内容相匹配的行时,它就会跳过将其写出的内容。然后,它删除文件内容并放入StringBuilder变量内容。
public void removeLineFromFile(String lineToRemove, File f) throws FileNotFoundException, IOException{
//Reading File Content and storing it to a StringBuilder variable ( skips lineToRemove)
StringBuilder sb = new StringBuilder();
try (Scanner sc = new Scanner(f)) {
String currentLine;
while(sc.hasNext()){
currentLine = sc.nextLine();
if(currentLine.equals(lineToRemove)){
continue; //skips lineToRemove
}
sb.append(currentLine).append("\n");
}
}
//Delete File Content
PrintWriter pw = new PrintWriter(f);
pw.close();
BufferedWriter writer = new BufferedWriter(new FileWriter(f, true));
writer.append(sb.toString());
writer.close();
}