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

发布于 2024-10-07 01:04:14 字数 753 浏览 3 评论 0原文

我有一个程序可以读取文本文件并将其处理为分成几个部分。

如何更改程序以允许程序在使用 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("============================================================");
        }
    }
}

I have a program which reads a text file and processes it to be separated into sections.

How can the program be changed to allow the program to skip reading the first 5 lines of the file while using the Stream Reader to read the file?

The code:

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("============================================================");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

感情洁癖 2024-10-14 01:04:14

尝试以下操作

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

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

Try the following

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

// Read the rest
string remainingText = tr.ReadToEnd();
霊感 2024-10-14 01:04:14

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

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();
}

If the lines are fixed then the most efficient way is as follows:

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();
    }
}

And if the lines vary in length then you'll have to just read them in a line at a time as follows:

using (var sr = new StreamReader("file"))
{
    for (int i = 1; i <= 5; ++i)
        sr.ReadLine();
}
明媚殇 2024-10-14 01:04:14

如果您想在程序中多次使用它,那么最好创建一个继承自 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);

If you want to use it more times in your program then it maybe a good idea to make a custom class inherited from StreamReader with the ability to skip lines.

Something like this could do:

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

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

after this you could use the SkippableStreamReader's function to skip lines.
Example:

SkippableStreamReader exampleReader = new SkippableStreamReader("file_to_read");

//do stuff
//and when needed
exampleReader.SkipLines(number_of_lines_to_skip);
少女的英雄梦 2024-10-14 01:04:14

我将在列表中添加另外两个建议。

如果总是有一个文件,并且您只会阅读,我建议这样做:

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();
        }
    }
}

迭代器块将在您完成后自动清理。 这里是 Jon Skeet 撰写的一篇文章,深入探讨了它的工作原理(向下滚动到“最后......”部分)。

I'll add two more suggestions to the list.

If there will always be a file, and you will only be reading, I suggest this:

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

File.ReadLines doesn't block the file from others and only loads into memory necessary lines.

If your stream can come from other sources then I suggest this approach:

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();
        }
    }
}

The Iterator block will automatically clean itself up once you are done with it. Here is an article by Jon Skeet going in depth into how that works exactly (scroll down to the "And finally..." section).

惯饮孤独 2024-10-14 01:04:14

我猜这很简单:

    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("============================================================");
        }
    }

I'd guess it's as simple as:

    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("============================================================");
        }
    }
唐婉 2024-10-14 01:04:14

带有 ReadLineReadToEndStreamReader 实际上会将字节读取到内存中,即使您没有处理这些行,它们也会已加载,这会在大文件(10+ MB)的情况下影响应用程序性能。

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

  1. 如果您知道行长度,您可以计算位置并使用 Stream.Seek 移动到那里。这是跳过流内容而不阅读它的最有效方法。这里的问题是你很少知道线的长度。
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
}
  1. 如果您不知道行长度,则必须逐行阅读并跳过它们,直到到达所需的行号。这里的问题是行数很高,你会受到性能影响
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
}

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

using(var reader = new StreamReader(fileName) )
{
   reader.BaseStream.Seek(0, SeekOrigin.End);

   // You can wait here for other processes to write into this file and then the ReadLine will provide you with that content

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

The StreamReader with ReadLine or ReadToEnd will actually go and read the bytes into the memory, even if you are not processing these lines, they will be loaded, which will affect the app performance in case of big files (10+ MB).

If you want to skip a specific number of lines you need to know the position of the file you want to move to, which gives you two options:

  1. If you know the line length you can calculate the position and move there with Stream.Seek. This is the most efficient way to skip stream content without reading it. The issue here is that you can rarely know the line length.
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
}
  1. If you don't know the line length, you have to read line by line and skip them until you get to the line number desired. The issue here is that is the line number is high, you will get a performance hit
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
}

And if you need just skip everything, you should do it without reading all the content into memory:

using(var reader = new StreamReader(fileName) )
{
   reader.BaseStream.Seek(0, SeekOrigin.End);

   // You can wait here for other processes to write into this file and then the ReadLine will provide you with that content

   var myNextLine = reader.ReadLine();
   // TODO: process the line
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文