C#如何使用Stream Reader读取文本文件时跳过行数?

时间:2010-12-11 18:44:59

标签: c# lines

我有一个程序,它读取文本文件并对其进行处理,将其分成几个部分。

所以问题是如何更改程序以允许程序在使用Stream Reader读取文件时跳过读取文件的前5行?

有人可以告知代码吗?谢谢!

代码:

class Program
{
    static void Main(string[] args)
    {
        TextReader tr = new StreamReader(@"C:\Test\new.txt");

        String SplitBy = "----------------------------------------";

        // Skip first 5 lines of the text file?
        String fullLog = tr.ReadToEnd();

        String[] sections = fullLog.Split(new string[] { SplitBy }, StringSplitOptions.None);

        //String[] lines = sections.Skip(5).ToArray();

        foreach (String r in sections)
        {
            Console.WriteLine(r);
            Console.WriteLine("============================================================");
        }
    }
}

6 个答案:

答案 0 :(得分:25)

尝试以下

// Skip 5 lines
for(var i = 0; i < 5; i++) {
  tr.ReadLine();
}

// Read the rest
string remainingText = tr.ReadToEnd();

答案 1 :(得分:11)

如果线条是固定的,那么最有效的方法如下:

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin);
    using( StreamReader reader = new StreamReader(stream) )
    {
        string line = reader.ReadLine();
    }
}

如果线条的长度不同,那么你必须一次只读一行:

using (var sr = new StreamReader("file"))
{
    for (int i = 1; i <= 5; ++i)
        sr.ReadLine();
}

答案 2 :(得分:8)

如果你想在你的程序中多次使用它,那么从StreamReader继承自定义类并跳过行是一个好主意。

这样的事情可以做到:

class SkippableStreamReader : StreamReader
{
    public SkippableStreamReader(string path) : base(path) { }

    public void SkipLines(int linecount)
    {
        for (int i = 0; i < linecount; i++)
        {
            this.ReadLine();
        }
    }
}

之后你可以使用SkippableStreamReader的函数跳过行。 例如:

SkippableStreamReader exampleReader = new SkippableStreamReader("file_to_read");

//do stuff
//and when needed
exampleReader.SkipLines(number_of_lines_to_skip);

答案 3 :(得分:5)

我会在列表中再添加两条建议。

如果总会有文件,而您只是在阅读,我建议:

var lines = File.ReadLines(@"C:\Test\new.txt").Skip(5).ToArray();

File.ReadLines不会阻止来自其他人的文件,只会加载到内存中必要的行。

如果您的信息流可以来自其他来源,那么我建议采用这种方法:

class Program
{
    static void Main(string[] args)
    {
        //it's up to you to get your stream
        var stream = GetStream();

        //Here is where you'll read your lines. 
        //Any Linq statement can be used here.
        var lines = ReadLines(stream).Skip(5).ToArray();

        //Go on and do whatever you want to do with your lines...
    }
}

public IEnumerable<string> ReadLines(Stream stream)
{
    using (var reader = new StreamReader(stream))
    {
        while (!reader.EndOfStream)
        {
            yield return reader.ReadLine();
        }
    }
}

完成后,Iterator块会自动清理。 Here是Jon Skeet的一篇文章,深入探讨了它的工作原理(向下滚动到&#34;最后......&#34;部分)。

答案 4 :(得分:1)

我猜它就像这样简单:

    static void Main(string[] args)
    {
        var tr = new StreamReader(@"C:\new.txt");

        var SplitBy = "----------------------------------------";

        // Skip first 5 lines of the text file?
        foreach (var i in Enumerable.Range(1, 5)) tr.ReadLine();
        var fullLog = tr.ReadToEnd(); 

        String[] sections = fullLog.Split(new string[] { SplitBy }, StringSplitOptions.None);

        //String[] lines = sections.Skip(5).ToArray();

        foreach (String r in sections)
        {
            Console.WriteLine(r);
            Console.WriteLine("============================================================");
        }
    }

答案 5 :(得分:0)

带有StreamReaderReadLine的{​​{1}}实际上会去并将字节读入内存,即使您不处理这些行,它们也会被加载,这会影响大文件(10+ MB)时的应用性能。

如果要跳过特定的行数,则需要知道要移动到的文件的位置,这为您提供了两种选择:

  1. 如果您知道线长,则可以计算位置并使用Stream.Seek移动到该位置。这是跳过流内容而不读取内容的最有效方法。这里的问题是您很少知道行长。
ReadToEnd
  1. 如果您不知道行长,则必须逐行阅读并跳过它们,直到获得所需的行号。这里的问题是行数很高,您将获得性能上的成功
var linesToSkip = 10;
using(var reader = new StreamReader(fileName) )
{
    reader.BaseStream.Seek(lineLength * (linesToSkip - 1), SeekOrigin.Begin);
    var myNextLine = reader.ReadLine();
    // TODO: process the line
}

如果只需要跳过所有内容,则应在不将所有内容读入内存的情况下执行此操作:

var linesToSkip = 10;
using (var reader = new StreamReader(fileName))
{
    for (int i = 1; i <= linesToSkip; ++i)
        reader.ReadLine();

    var myNextLine = reader.ReadLine();
    // TODO: process the line
}