7

我在 stackoverflow 上找到了这段代码,用于从文本文件中删除第一行和最后一行。

但是我不知道如何将此代码组合成一个,以便从单个文件中删除第一行和最后一行?

我尝试的是使用 streamreader 读取文件,然后跳过第一行和最后一行,然后 streamwriter 写入新文件,但无法获得正确的结构。

删除第一行。

var lines = System.IO.File.ReadAllLines("test.txt");
System.IO.File.WriteAllLines("test.txt", lines.Skip(1).ToArray());

删除最后一行。

   var lines = System.IO.File.ReadAllLines("...");
System.IO.File.WriteAllLines("...", lines.Take(lines.Length - 1).ToArray());
4

3 回答 3

21

您可以链接SkipTake方法。请记住在方法中减去适当的行数Take。你在开始时跳过的越多,剩下的行就越少。

var filename = "test.txt";
var lines = System.IO.File.ReadAllLines(filename);
System.IO.File.WriteAllLines(
    filename, 
    lines.Skip(1).Take(lines.Length - 2)
);
于 2013-06-24T11:28:32.677 回答
6

虽然在这种情况下可能不是主要问题,但现有答案都依赖于首先将文件的全部内容读入内存。对于小文件,这可能很好,但如果您正在处理非常大的文件,这可能会令人望而却步。

创建SkipLast与现有SkipLinq 方法等效的方法相当简单:

public static class SkipLastExtension
{
    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int count)
    {
        var queue = new Queue<T>();
        foreach (var item in source)
        {
            queue.Enqueue(item);
            if (queue.Count > count)
            {
                yield return queue.Dequeue();
            }
        }
    }
}

如果我们还定义了一种方法,该方法允许我们枚举文件的每一行而不预先缓冲整个文件(根据:https ://stackoverflow.com/a/1271236/381588 ):

static IEnumerable<string> ReadFrom(string filename)
{
    using (var reader = File.OpenText(filename))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

然后我们可以使用以下单行代码编写一个新文件,其中包含原始文件中的所有行,除了第一行和最后一行:

File.WriteAllLines("output.txt", ReadFrom("input.txt").Skip(1).SkipLast(1));

毫无疑问,这比已经在此处发布的其他答案(相当多)更多代码,但应该适用于基本上任何大小的文件,(以及为可能有用的SkipLast扩展方法提供代码)。

于 2013-06-24T12:16:15.420 回答
1

这是另一种使用的方法ArraySegment<string>

var lines = File.ReadAllLines("test.txt");
File.WriteAllLines("test.txt", new ArraySegment<string>(lines, 1, lines.Length-2));
于 2013-06-24T11:41:33.670 回答