从文本文件中删除行的有效方法

我需要从文本文件中删除某一行。 这样做最有效的方法是什么? 文件可能很大(超过百万条记录)。

更新:下面是我正在使用的代码,但我不确定它是否好。

internal void DeleteMarkedEntries() { string tempPath=Path.GetTempFileName(); using (var reader = new StreamReader(logPath)) { using (var writer = new StreamWriter(File.OpenWrite(tempPath))) { int counter = 0; while (!reader.EndOfStream) { if (!_deletedLines.Contains(counter)) { writer.WriteLine(reader.ReadLine()); } ++counter; } } } if (File.Exists(tempPath)) { File.Delete(logPath); File.Move(tempPath, logPath); } } 

这样做最直接的方式可能是最好的,将整个文件写入一个新文件,写下除了你不想要的那些之外的所有行。

或者,打开文件以进行随机访问。

阅读到想要“删除”该行的位置。 跳过要删除的行,并读取该字节数(包括CR + LF – 如果需要),在删除的行上写入该字节数,按字节数提前两个位置并重复直到文件结束。

希望这可以帮助。

编辑 – 现在我可以看到你的代码了

 if (!_deletedLines.Contains(counter)) { writer.WriteLine(reader.ReadLine()); } 

不行,如果它不是你想要的那一行, 你还是想读它就是不写它 。 上面的代码既不会读取也不会写入。 新文件将与旧文件完全相同。

你想要的东西

 string line = reader.ReadLine(); if (!_deletedLines.Contains(counter)) { writer.WriteLine(line); } 

文本文件是连续的,因此在删除行时,您必须向上移动以下所有行。 你可以使用文件映射(你可以通过PInvoke调用的win32 api)使这个操作不那么痛苦,但你肯定应该考虑使用一个非顺序结构的文件,这样你就可以将一行标记为已删除,而无需真正删除它来自文件…特别是如果它应该发生的事情。

如果我记得文件映射Api应该添加到.Net 4。

  try{ Scanner reader = new Scanner(new File("D:/seenu.txt")); System.out.println("Enter serial number:"); String sl1=bufRead.readLine(); System.out.print("Please Enter The ServerName:"); String name=bufRead.readLine(); System.out.println("Please Enter The IPAddress"); String ipa=bufRead.readLine(); System.out.println("Line Deleted."); PrintWriter writer = new PrintWriter(new FileWriter(new File("D:/user.txt")),true); //for(int w=0; w 

如果您必须使用文本文件并且无法切换到数据库,可能您想在行的开头指定一个奇怪的符号来表示“删除行”。 让你的解析器忽略这些行,比如配置文件中的注释行等。

然后有一个像Outlook这样的定期“紧凑”例程,大多数数据库系统都会这样做,它会重写整个文件,不包括删除的行。

我强烈建议使用Think Before Coding的答案来推荐数据库或其他结构化文件。

根据确切的“删除”,您的最佳解决方案可能是用空格覆盖违规行。 出于多种目的(包括人类消费),这相当于直接删除该行。 如果生成的空白行有问题,并且您确定永远不会删除第一行,则可以通过用两个空格覆盖CRLF来将空格附加到上一行。

(基于对Bork Blatt的回答的评论)

使用文件映射将文件移动到内存,例如Think Before Coding ,并在内存和写入磁盘后删除。
阅读此文件阅读基准 – C#
C#访问内存映射文件

在我的博客中,我对C#中的各种I / O方法进行了基准测试,以确定最有效的文件I / O方式。 通常,最好使用Windows ReadFile和WriteFile函数。 读取文件的下一个最快方法是通过FileStream。 要获得良好的性能,请一次读取块中的文件,而不是一次读取一行,然后进行自己的解析。 您可以从我的博客下载的代码为您提供了如何执行此操作的示例。 还有一个C#类封装了Windows ReadFile / WriteFilefunction,并且非常易于使用。 有关详情请访问我的博客:

http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp

Bob Bryan MCSD

将您的文件读入非删除行的字典中将int设置为0,您需要将其标记为已删除的set int为1.使用KeyValuePair提取不需要删除的行并将其写入新文件。

 Dictionary output = new Dictionary(); // read line from file ... // if need to delete line then set int value to 1 // otherwise set int value to 0 if (deleteLine) { output[line] = 1; } else { output[line] = 0; } // define the no delete List List nonDeleteList = new List(); // use foreach to loop through each item in nonDeleteList and add each key // who's value is equal to zero (0) to the nonDeleteList. foreach (KeyValuePair kvp in output) { if (kvp.Value == 0) { nonDeleteList.Add(kvp.Key); } } // write the nondeletelist to the output file File.WriteAllLines("OUTPUT_FILE_NAME", nonDeleteList.ToArray()); 

而已。