虽然在这种情况下可能不是主要问题,但现有答案都依赖于首先将文件的全部内容读入内存。对于小文件,这可能很好,但如果您正在处理非常大的文件,这可能会令人望而却步。
创建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扩展方法提供代码)。