使用streamreader找到一行后如何读取接下来的x行数

问题描述 投票:0回答:4

我想在文本文件中搜索包含“Performance Stats:”的行,然后打印接下来的 20 行左右,因为它们是性能统计表。我正在使用 Streamreader。

string pathToFile = "\\host\c$\temp\logs\myPerformanceFile.txt"

using (var filestream = new FileStream(pathToFile, FileMode.Open, FileAccess.Read,                               FileShare.ReadWrite))
using (var streamReader = new StreamReader(filestream, Encoding.Default))
{
    string line;
    while ((line = streamReader.ReadLine()) != null)
    {
        if (line.Contains("Performance Stats:"))
        {
            Console.WriteLine(line)
        }
    }
}

我试图找到每个统计数据的标题栏。但 20 行看起来有点混乱,例如文件中有 5 个表,我正在使用相同的搜索参数进行解析..但我只想要其中一个表中的数据。

        if (line.Contains("Timings:"))
        {
            Console.WriteLine(line)
        }
        if (line.Contains("Downloads:")) 
        {
            Console.WriteLine(line)
        }
        if (line.Contains("Reset")) 
        {
            Console.WriteLine(line)
        }
c# streamreader
4个回答
1
投票

我会使用

File.ReadLines
,它也在引擎盖下“流式传输”行,因此不会一次读取所有行。您可以使用 LINQ 来简化它并返回自定义类
PerformanceStats
:

public class PerformanceStats
{
    public string Timings{get; set;}
    public string Downloads{get; set;}
    public string Reset{get; set;}
}

void Main()
{
    PerformanceStats stats = GetPerformanceStats(@"\\host\c$\temp\logs\myPerformanceFile.txt");
}

static PerformanceStats GetPerformanceStats(string filePath)
{
    if(!System.IO.File.Exists(filePath))
    {
        return null;
    }
    
    string[] properties = {"Timings:", "Downloads:", "Reset:"};
    List<string> lines = System.IO.File.ReadLines(filePath)
        .SkipWhile(line => !line.Contains("Performance Stats:"))
        .Take(20)
        .Where(line => properties.Any(p => line.Contains(p, StringComparison.InvariantCultureIgnoreCase)))
        .ToList();
    return new PerformanceStats
    {
        Timings = lines.FirstOrDefault(l => l.Contains("Timings:", StringComparison.InvariantCultureIgnoreCase)),
        Downloads = lines.FirstOrDefault(l => l.Contains("Downloads:", StringComparison.InvariantCultureIgnoreCase)),
        Reset = lines.FirstOrDefault(l => l.Contains("Reset:", StringComparison.InvariantCultureIgnoreCase))
    };
}

0
投票

如果我理解正确,当它包含一组字符串中的任何字符串时,您想要打印

line

你可以先把所有想要查找的字符串放入一个数组中:

var titles = new string[] {
    "Performance Stats:", "Timings:", "Downloads:" // etc
};

然后在此数组上使用

Any
表示“如果
line
包含在任何
titles
...”中:

if (titles.Any(line.Contains))
{
    Console.WriteLine(line);
}

0
投票

您可以使用柜台。例如:

int counter = 0; 

while ((line = streamReader.ReadLine()) != null)
{
    if (line.Contains("Performance Stats:")) // Trigger
    {
        counter = 20; // Number of lines to print
    }
    if (counter > 0) {
        Console.WriteLine(line);
        counter--;
    }
}

这样您就可以在触发后打印 X 下一行。

如果您在写入该行后放置触发器,它当然会跳过带有条件的行。


0
投票

如果您只是阅读整行,则不需要使用

StreamReader
。您可以改为使用
File.ReadLines()

因为返回一个

IEnumerable<string>()
,所以你可以使用 Linq 的
SkipWhile
Take
来获取你需要的项目:

var lines = File.ReadLines(pathToFile)
    .SkipWhile(line => line != "Performance Stats:")
    .Take(21); // 21 = Initial line + 20 more.

Console.WriteLine(string.Join("\n", lines));

当然,真正的代码应该检查

lines
实际上包含任何内容。

© www.soinside.com 2019 - 2024. All rights reserved.