如何删除文本文件的前X行?

4
对于我的项目,我必须删除纯文本文件的前X行。我之所以说X,是因为我需要多次执行此例程,每次要删除的行数都不同,但它们始终从开头开始,删除前X行,然后将结果输出到同一文件中。
我考虑采取以下方式,该方式是我从其他教程和示例中拼凑而成的:
String line = null;

String tempFile = Path.GetTempFileName();
String filePath = openFileDialog.FileName;

int line_number = 0;
int lines_to_delete = 25;

using (StreamReader reader = new StreamReader(originalFile)) {
    using (StreamWriter writer = new StreamWriter(tempFile)) {
        while ((line = reader.ReadLine()) != null) {
            line_number++;

            if (line_number <= lines_to_delete)
                continue;

            writer.WriteLine(line);
        }
    }
}

if (File.Exists(tempFile)) {
    File.Delete(originalFile);
    File.Move(tempFile, originalFile);
}

但是,我不知道这是否可行,因为有一些小细节问题,例如行号从第0行开始或其他问题......此外,我也不知道它在效率和形式方面是否是良好的代码。
非常感谢。
4个回答

10

我喜欢简短的...

File.WriteAllLines(
    fileName,
    File.ReadAllLines(fileName).Skip(numberLinesToSkip).ToArray());

不错的干净解决方案。但如果源文件太大,它会导致问题,因为它会将整个文件读入内存。 - LukeH
是的,它确实很干净,但正如我在查理的帖子中提到的那样,该文件非常大,这个应用程序将无法在强大的机器上运行...不过还是谢谢你;我不知道你使用的所有方法,我学到了一些新东西! - ankushg

6

没问题,看起来不会出现你担心的那种一位偏差问题。然而,一个更简洁的方法是使用两个单独的循环——一个仅用于计算输入文件的前X行(什么也不做),另一个仅将其他行从输入复制到输出。也就是说,不要使用你的单个while循环,改为使用以下方式:

    while ((line = reader.ReadLine()) != null) {
        line_number++;

        if (line_number > lines_to_delete)
            break;
    }

    while ((line = reader.ReadLine()) != null) {
        writer.WriteLine(line);
    }

这能够正常工作是因为当我再次执行reader.ReadLine()时,它会从上一次读取的位置继续读取,对吗?如果我想要创建另一个名为“reader”的读取器(因为这将在一个更大的循环中重复执行此过程多次),我只需要关闭“reader”,然后当我创建另一个读取器时,它会从文件的开头重新开始读取,对吗? - ankushg
@Unk,是的,在这条评论中两个问题都是。 - Alex Martelli

2

我喜欢你的方法,我认为它没有问题。如果你确定这些文件很小,那么其他建议可能会减少一些代码量,如果这对你很重要。

一个稍微简洁的版本:

using (StreamReader reader = new StreamReader(originalFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
    while(lines_to_delete-- > 0)
        reader.ReadLine();
    while ((line = reader.ReadLine()) != null)
        writer.WriteLine(line);
}

0
你可以将文件读入行数组中,忽略前几个元素,然后将其余部分写回。
这种方法的缺点是它会消耗内存中文件的大小。虽然你的方法(尽管相当难以阅读,无意冒犯)没有这个内存问题。不过,如果文件不太大,就不必担心内存使用情况。
例如:
string[] lines = System.IO.File.ReadAllLines("YourFile.txt").Skip(10).ToArray();
System.IO.File.WriteAllLines("OutFile.txt", lines);

是的,主要问题是文件非常大,而且程序运行的计算机并不是顶尖的。我已经使用了一堆数组来处理一些东西,所以我选择了读取和即时写入的方法。无论如何,感谢您的帮助。 - ankushg
糟糕,我的错,忘记了ToArray()。 - user47322

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接