小编典典

在C#中逐行读取文件

c#

我正在尝试读取一些文本文件,其中每一行都需要处理。目前,我只是使用StreamReader,然后分别读取每一行。

我想知道是否有更有效的方法(就LoC和可读性而言)使用LINQ来做到这一点,而又不影响运营效率。我所看到的示例涉及将整个文件加载到内存中,然后进行处理。但是,在这种情况下,我认为这样做不会非常有效。在第一个示例中,文件最多可以存储50k,在第二个示例中,不需要读取文件的所有行(大小通常小于10k)。

您可能会争辩说,如今对于这些小文件而言,这实际上已不重要,但是我相信这种方法会导致代码效率低下。

第一个例子:

// Open file
using(var file = System.IO.File.OpenText(_LstFilename))
{
    // Read file
    while (!file.EndOfStream)
    {
        String line = file.ReadLine();

        // Ignore empty lines
        if (line.Length > 0)
        {
            // Create addon
            T addon = new T();
            addon.Load(line, _BaseDir);

            // Add to collection
            collection.Add(addon);
        }
    }
}

第二个例子:

// Open file
using (var file = System.IO.File.OpenText(datFile))
{
    // Compile regexs
    Regex nameRegex = new Regex("IDENTIFY (.*)");

    while (!file.EndOfStream)
    {
        String line = file.ReadLine();

        // Check name
        Match m = nameRegex.Match(line);
        if (m.Success)
        {
            _Name = m.Groups[1].Value;

            // Remove me when other values are read
            break;
        }
    }
}

阅读 479

收藏
2020-05-19

共1个答案

小编典典

您可以使用迭代器块轻松编写基于LINQ的行读取器:

static IEnumerable<SomeType> ReadFrom(string file) {
    string line;
    using(var reader = File.OpenText(file)) {
        while((line = reader.ReadLine()) != null) {
            SomeType newRecord = /* parse line */
            yield return newRecord;
        }
    }
}

或让乔恩开心:

static IEnumerable<string> ReadFrom(string file) {
    string line;
    using(var reader = File.OpenText(file)) {
        while((line = reader.ReadLine()) != null) {
            yield return line;
        }
    }
}
...
var typedSequence = from line in ReadFrom(path)
                    let record = ParseLine(line)
                    where record.Active // for example
                    select record.Key;

那么您将ReadFrom(...)获得一个无缓冲的懒惰评估序列,非常适合Where等。

请注意,如果使用OrderBy或standard GroupBy,它将必须在内存中缓冲数据;如果需要分组和聚合,则“
PushLINQ”具有一些精美的代码,可让您对数据执行聚合但将其丢弃(不进行缓冲)。乔恩的解释在这里

2020-05-19