如何从C#中的文本文件中删除一行?

ali*_*scu 44 c# text-files

我有一个问题:如何从C#中的文本文件中删除一行?

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编码的.


Sas*_*cha 27

读取文件,删除内存中的行并将内容放回文件(覆盖).如果文件很大,您可能希望将其读取为行,并创建临时文件,稍后替换原始文件.


Jon*_*eet 19

我同意John Saunders,这不是C#特有的.但是,要回答你的问题:你基本上需要重写文件.有两种方法可以做到这一点.

  • 将整个文件读入内存(例如File.ReadAllLines)
  • 删除有问题的行(在这种情况下,最简单的方法是将字符串数组转换为a List<string>然后删除行)
  • 将所有其余行写回(例如File.WriteAllLines) - 可能会List<string>再次使用转换为字符串数组ToArray

这意味着你必须知道你已经有足够的内存了.替代:

  • 打开输入文件和新输出文件(作为TextReader/ TextWriter,例如with File.OpenTextFile.CreateText)
  • 读一行(TextReader.ReadLine) - 如果你不想删除它,把它写到输出文件(TextWriter.WriteLine)
  • 当你读完所有的行后,关闭阅读器和编写器(如果你使用using两者的语句,这将自动发生)
  • 如果要将输入替换为输出,请删除输入文件,然后将输出文件移动到位.


Pra*_*ran 8

要从文本文件中删除项目,请先将所有文本移动到列表中,然后删除所需的项目.然后将列表中存储的文本写入文本文件:

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)


Leo*_* P. 5

我写了一个方法来从文件中删除行。

该程序使用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)