C# 从文本文件中删除一行的有效方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/532217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Efficient way to delete a line from a text file
提问by Valentin Vasilyev
I need to delete a certain line from a text file. What is the most efficient way of doing this? File can be potentially large(over million records).
我需要从文本文件中删除某一行。这样做的最有效方法是什么?文件可能很大(超过百万条记录)。
UPDATE: below is the code I'm currently using, but I'm not sure if it is good.
更新:下面是我目前使用的代码,但我不确定它是否好。
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);
}
}
采纳答案by Binary Worrier
The most straight forward way of doing this is probably the best, write the entire file out to a new file, writing all lines except the one(s) you don't want.
这样做的最直接的方法可能是最好的,将整个文件写入一个新文件,写入除您不想要的行之外的所有行。
Alternatively, open the file for random access.
或者,打开文件进行随机访问。
Read to the point where you want to "delete" the line. Skip past the line to delete, and read that number of bytes (including CR + LF - if necessary), write that number of bytes over the deleted line, advance both locations by that count of bytes and repeat until end of file.
阅读到要“删除”该行的点。跳过要删除的行,然后读取该字节数(包括 CR + LF - 如有必要),在已删除行上写入该字节数,按该字节数推进两个位置并重复直到文件结束。
Hope this helps.
希望这可以帮助。
EDIT- Now that I can see your code
编辑- 现在我可以看到你的代码
if (!_deletedLines.Contains(counter))
{
writer.WriteLine(reader.ReadLine());
}
Will not work, if its the line you don't want, you still want to read it, just not write it. The above code will neither read it or write it. The new file will be exactly the same as the old.
行不通,如果它是您不想要的行,您仍然想阅读它,只是不写它。上面的代码既不会读也不会写。新文件将与旧文件完全相同。
You want something like
你想要类似的东西
string line = reader.ReadLine();
if (!_deletedLines.Contains(counter))
{
writer.WriteLine(line);
}
回答by thinkbeforecoding
Text files are sequential, so when deleting a line, you'll have to move all the following lines up. You can use file mapping (a win32 api that you can call through PInvoke) to make this operation a bit less painfull, but you surelly should considere using a non sequential structure for you file so that you can mark a line as deleted without realy removing it from the file... Especially if it should happen frenquently.
文本文件是连续的,因此在删除一行时,您必须将以下所有行向上移动。您可以使用文件映射(您可以通过 PInvoke 调用的 win32 api)使此操作不那么痛苦,但是您肯定应该考虑为您的文件使用非顺序结构,以便您可以将一行标记为已删除而无需真正删除它来自文件......特别是如果它应该经常发生的话。
If I've remember File Mapping Api should be added to .Net 4.
如果我记得应该将文件映射 Api 添加到 .Net 4。
回答by Bork Blatt
If you absolutely haveto use a text file and cannot switch to a database, maybe you want to designate a wierd symbol at the beginning of a line to mean "line deleted". Just have your parser ignore those lines, like comment lines in config files etc.
如果您绝对必须使用文本文件并且无法切换到数据库,也许您想在一行的开头指定一个奇怪的符号来表示“已删除行”。只需让您的解析器忽略这些行,例如配置文件中的注释行等。
Then have a periodic "compact" routine like Outlook, and most database systems do, which re-writes the entire file excluding the deleted lines.
然后有一个定期的“紧凑”例程,如 Outlook,大多数数据库系统都会这样做,它会重写整个文件,不包括已删除的行。
I would strongly go with Think Before Coding's answer recommending a database or other structured file.
我强烈建议使用 Think Before Coding 的答案推荐数据库或其他结构化文件。
回答by lsalamon
Move you file to memory using File Mapping, like Think Before Codingdid, and made deletions on memory and after write to disk.
Read this File Read Benchmarks - C#
C# accessing memory map file
使用文件映射将您的文件移动到内存,就像在编码之前思考一样,并在内存和写入磁盘后进行删除。
Read this File Read Benchmarks - C#
C# 访问内存映射文件
回答by MSalters
Depending on what exactly counts as "deleting", your best solution may be to overwrite the offending line with spaces. For many purposes (including human consumption), this is equivalent to deleting the line outright. If the resulting blank line is a problem, and you are sure you'll never delete the first line, you can append the spaces to the previous line by also overwriting the CRLF with two spaces.
根据究竟什么算是“删除”,您最好的解决方案可能是用空格覆盖有问题的行。对于许多目的(包括人类消费),这相当于彻底删除该行。如果生成的空行有问题,并且您确定永远不会删除第一行,则可以通过用两个空格覆盖 CRLF 来将空格附加到前一行。
(Based on the comment to Bork Blatt's answer)
(基于对 Bork Blatt 回答的评论)
回答by willjr20
Read your file into a Dictionary on non delete lines set the int to 0 on line you need to mark as deleted set int to 1. Use a KeyValuePair to extract the lines that don't needed to be deleted and write them to a new file.
在非删除行上将文件读入字典将 int 设置为 0 在需要标记为已删除的行上将 int 设置为 1。使用 KeyValuePair 提取不需要删除的行并将它们写入新文件.
Dictionary<string, int> output = new Dictionary<string, int>();
// 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<string> nonDeleteList = new List<string>();
// 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<string, int> 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());
That's it.
就是这样。
回答by Bob Bryan
In my blog, I have benchmarked various I/O methods from C# in order to determine the most efficient way of doing file I/O. In general, you are better off using the Windows ReadFile and WriteFile functions. The next fastest way to read files in is through FileStream. To get good performance, read the files in blocks at a time instead of a line at a time and then do your own parsing. The code that you can download from my blog gives you an example on how to do this. There is also a C# class that encapsulates the Windows ReadFile / WriteFile functionality and is quite easy to use. See my blog for details at:
在我的博客中,我对 C# 中的各种 I/O 方法进行了基准测试,以确定执行文件 I/O 的最有效方法。通常,最好使用 Windows ReadFile 和 WriteFile 函数。读取文件的下一个最快方法是通过 FileStream。要获得良好的性能,请一次读取块中的文件,而不是一次读取一行,然后进行自己的解析。您可以从我的博客下载的代码为您提供了如何执行此操作的示例。还有一个 C# 类,它封装了 Windows ReadFile / WriteFile 功能并且非常易于使用。有关详细信息,请参阅我的博客:
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp
Bob Bryan MCSD
鲍勃·布莱恩 MCSD
回答by Rajkumar
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<n; w++)
writer.write(reader.nextLine());
reader.nextLine();
while(reader.hasNextLine())
writer.write(reader.nextLine());
} catch(Exception e){
System.err.println("Enjoy the stack trace!");
e.printStackTrace();
}