C# 如何使用c删除具有行号的行?

C# 如何使用c删除具有行号的行?,c#,string,file-io,C#,String,File Io,我的名为test.txt的文件包含 本文档分为大约5个逻辑部分,首先是功能和结构概述,然后是内置列和单元类型概述。接下来是使用数据的概述,然后是特定主要功能的概述。最后,“最佳实践”部分总结了本文件的主要部分 现在我想删除文件的第二行。 如何使用c来实现它 提前谢谢。 Naveenkumar您可以通过将文本拆分为\n,然后使用LINQ选择要保留的行并重新连接它们来实现此目的 var lineNum=5; var lines=File .ReadAllText(@"src.txt")

我的名为test.txt的文件包含

本文档分为大约5个逻辑部分,首先是功能和结构概述,然后是内置列和单元类型概述。接下来是使用数据的概述,然后是特定主要功能的概述。最后,“最佳实践”部分总结了本文件的主要部分

现在我想删除文件的第二行。 如何使用c来实现它

提前谢谢。
Naveenkumar

您可以通过将文本拆分为\n,然后使用LINQ选择要保留的行并重新连接它们来实现此目的

var lineNum=5;
var lines=File
    .ReadAllText(@"src.txt")
    .Split('\n');
var outTxt=String
    .Join(
        "\n",
        lines
            .Take(lineNum)
            .Concat(lines.Skip(lineNum+1))
            .ToArray()
    );

这是我要做的。其优点是,您不必一次将文件全部存储在内存中,因此对于大小不同的文件,只要每个文件中包含的行具有相似的长度,内存需求就应该相似。缺点是您不能通过管道返回到同一个文件-您必须在删除和移动之后进行处理

对于您的简单示例来说,扩展方法可能有些过分,但这是我一次又一次依赖的两种扩展方法,以及ReadFile方法,因此我通常只需要在Main中编写代码

class Program
{
  static void Main()
  {
    var file = @"C:\myFile.txt";
    var tempFile = Path.ChangeExtension(file, "tmp");

    using (var writer = new StreamWriter(tempFile))
    {
      ReadFile(file)
      .FilterI((i, line) => i != 1)
      .ForEach(l => writer.WriteLine(l));    
    }

    File.Delete(file);
    File.Move(tempFile, file);
  }

  static IEnumerable<String> ReadFile(String file)
  {
    using (var reader = new StreamReader(file))
    {
      while (!reader.EndOfStream)
      {
        yield return reader.ReadLine();
      }
    }
  }
}

static class IEnumerableExtensions
{
  public static IEnumerable<T> FilterI<T>(
      this IEnumerable<T> seq, 
      Func<Int32, T, Boolean> filter)
  {
    var index = 0;

    foreach (var item in seq)
    {
      if (filter(index, item))
      {
        yield return item;
      }

      index++;
    }
  }

  public static void ForEach<T>(
      this IEnumerable<T> seq,
      Action<T> action)
  {
    foreach (var item in seq)
    {
      action(item);
    }
  }
}

这里有一个非常有效的方法

FileInfo x = new FileInfo(@"path\to\original");
string xpath = x.FullName;

FileInfo y = new FileInfo(@"path\to\temporary\new\file");

using (var reader = x.OpenText())
using (var writer = y.AppendText())
{
    // write 1st line
    writer.WriteLine(reader.ReadLine());

    reader.ReadLine(); // skip 2nd line

    // write all remaining lines
    while (!reader.EndOfStream)
    {
        writer.WriteLine(reader.ReadLine());
    }
}

x.Delete();
y.MoveTo(xpath);

第三段是否与这个问题相关?停止尝试改变文件数据+1-类似于我的原则,没有可重用性狂热!这段代码很短,也很正确,这是最主要的。但是,请注意,它会立即将整个文件的内容加载到内存中。因此,它的有用性取决于文件的大小和您必须空闲的内存量。这种方法会将整个文件加载到内存中,然后在内存中生成一个几乎没有第二行的副本。因此,当文件较大且存在内存限制时,应谨慎操作。
class Program
{
  static void Main()
  {
    var file = @"C:\myFile.txt";
    var tempFile = Path.ChangeExtension(file, "tmp");

    using (var writer = new StreamWriter(tempFile))
    {
      ReadFile(file)
      .FilterI((i, line) => i != 1)
      .ForEach(l => writer.WriteLine(l));    
    }

    File.Delete(file);
    File.Move(tempFile, file);
  }

  static IEnumerable<String> ReadFile(String file)
  {
    using (var reader = new StreamReader(file))
    {
      while (!reader.EndOfStream)
      {
        yield return reader.ReadLine();
      }
    }
  }
}

static class IEnumerableExtensions
{
  public static IEnumerable<T> FilterI<T>(
      this IEnumerable<T> seq, 
      Func<Int32, T, Boolean> filter)
  {
    var index = 0;

    foreach (var item in seq)
    {
      if (filter(index, item))
      {
        yield return item;
      }

      index++;
    }
  }

  public static void ForEach<T>(
      this IEnumerable<T> seq,
      Action<T> action)
  {
    foreach (var item in seq)
    {
      action(item);
    }
  }
}
FileInfo x = new FileInfo(@"path\to\original");
string xpath = x.FullName;

FileInfo y = new FileInfo(@"path\to\temporary\new\file");

using (var reader = x.OpenText())
using (var writer = y.AppendText())
{
    // write 1st line
    writer.WriteLine(reader.ReadLine());

    reader.ReadLine(); // skip 2nd line

    // write all remaining lines
    while (!reader.EndOfStream)
    {
        writer.WriteLine(reader.ReadLine());
    }
}

x.Delete();
y.MoveTo(xpath);