Mar*_*son 75
对于非常大的文件,我会做这样的事情
string tempFile = Path.GetTempFileName();
using(var sr = new StreamReader("file.txt"))
using(var sw = new StreamWriter(tempFile))
{
string line;
while((line = sr.ReadLine()) != null)
{
if(line != "removeme")
sw.WriteLine(line);
}
}
File.Delete("file.txt");
File.Move(tempFile, "file.txt");
Run Code Online (Sandbox Code Playgroud)
更新我最初在2009年写了这篇文章,我认为更新可能会很有趣.今天你可以使用LINQ和延迟执行来完成上述任务
var tempFile = Path.GetTempFileName();
var linesToKeep = File.ReadLines(fileName).Where(l => l != "removeme");
File.WriteAllLines(tempFile, linesToKeep);
File.Delete(fileName);
File.Move(tempFile, fileName);
Run Code Online (Sandbox Code Playgroud)
上面的代码几乎与第一个示例完全相同,逐行读取并在内存中保留最少量的数据.
尽管如此,免责声明可能是有序的.由于我们在这里讨论文本文件,因此您很少需要将磁盘用作中间存储介质.如果您没有处理非常大的日志文件,那么将内容读入内存应该没有问题,并且避免必须处理临时文件.
File.WriteAllLines(fileName,
File.ReadLines(fileName).Where(l => l != "removeme").ToList());
Run Code Online (Sandbox Code Playgroud)
请注意,.ToList
强制立即执行至关重要.另请注意,所有示例都假定文本文件是UTF-8编码的.
Jon*_*eet 19
我同意John Saunders,这不是C#特有的.但是,要回答你的问题:你基本上需要重写文件.有两种方法可以做到这一点.
File.ReadAllLines
)List<string>
然后删除行)File.WriteAllLines
) - 可能会List<string>
再次使用转换为字符串数组ToArray
这意味着你必须知道你已经有足够的内存了.替代:
TextReader
/ TextWriter
,例如with File.OpenText
和File.CreateText
)TextReader.ReadLine
) - 如果你不想删除它,把它写到输出文件(TextWriter.WriteLine
)using
两者的语句,这将自动发生)要从文本文件中删除项目,请先将所有文本移动到列表中,然后删除所需的项目.然后将列表中存储的文本写入文本文件:
List<string> quotelist=File.ReadAllLines(filename).ToList();
string firstItem= quotelist[0];
quotelist.RemoveAt(0);
File.WriteAllLines(filename, quotelist.ToArray());
return firstItem;
Run Code Online (Sandbox Code Playgroud)
小智 6
我扩展了Markus Olsson建议的内容,并提出了这个添加多个搜索字符串和几个事件的类:
public static class TextLineRemover
{
public static void RemoveTextLines(IList<string> linesToRemove, string filename, string tempFilename)
{
// Initial values
int lineNumber = 0;
int linesRemoved = 0;
DateTime startTime = DateTime.Now;
// Read file
using (var sr = new StreamReader(filename))
{
// Write new file
using (var sw = new StreamWriter(tempFilename))
{
// Read lines
string line;
while ((line = sr.ReadLine()) != null)
{
lineNumber++;
// Look for text to remove
if (!ContainsString(line, linesToRemove))
{
// Keep lines that does not match
sw.WriteLine(line);
}
else
{
// Ignore lines that DO match
linesRemoved++;
InvokeOnRemovedLine(new RemovedLineArgs { RemovedLine = line, RemovedLineNumber = lineNumber});
}
}
}
}
// Delete original file
File.Delete(filename);
// ... and put the temp file in its place.
File.Move(tempFilename, filename);
// Final calculations
DateTime endTime = DateTime.Now;
InvokeOnFinished(new FinishedArgs {LinesRemoved = linesRemoved, TotalLines = lineNumber, TotalTime = endTime.Subtract(startTime)});
}
private static bool ContainsString(string line, IEnumerable<string> linesToRemove)
{
foreach (var lineToRemove in linesToRemove)
{
if(line.Contains(lineToRemove))
return true;
}
return false;
}
public static event RemovedLine OnRemovedLine;
public static event Finished OnFinished;
public static void InvokeOnFinished(FinishedArgs args)
{
Finished handler = OnFinished;
if (handler != null) handler(null, args);
}
public static void InvokeOnRemovedLine(RemovedLineArgs args)
{
RemovedLine handler = OnRemovedLine;
if (handler != null) handler(null, args);
}
}
public delegate void Finished(object sender, FinishedArgs args);
public class FinishedArgs
{
public int TotalLines { get; set; }
public int LinesRemoved { get; set; }
public TimeSpan TotalTime { get; set; }
}
public delegate void RemovedLine(object sender, RemovedLineArgs args);
public class RemovedLineArgs
{
public string RemovedLine { get; set; }
public int RemovedLineNumber { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
用法:
TextLineRemover.OnRemovedLine += (o, removedLineArgs) => Console.WriteLine(string.Format("Removed \"{0}\" at line {1}", removedLineArgs.RemovedLine, removedLineArgs.RemovedLineNumber));
TextLineRemover.OnFinished += (o, finishedArgs) => Console.WriteLine(string.Format("{0} of {1} lines removed. Time used: {2}", finishedArgs.LinesRemoved, finishedArgs.TotalLines, finishedArgs.TotalTime.ToString()));
TextLineRemover.RemoveTextLines(new List<string> { "aaa", "bbb" }, fileName, fileName + ".tmp");
Run Code Online (Sandbox Code Playgroud)
我写了一个方法来从文件中删除行。
该程序使用using System.IO
.
看我的代码:
void File_DeleteLine(int Line, string Path)
{
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(Path))
{
int Countup = 0;
while (!sr.EndOfStream)
{
Countup++;
if (Countup != Line)
{
using (StringWriter sw = new StringWriter(sb))
{
sw.WriteLine(sr.ReadLine());
}
}
else
{
sr.ReadLine();
}
}
}
using (StreamWriter sw = new StreamWriter(Path))
{
sw.Write(sb.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)