C#阅读流

时间:2013-08-14 13:59:14

标签: c# file-io filestream

我想在C#中读取.txt文件,但我不会同时读取所有行。例如,考虑500行文本文件。我希望一个函数运行25次,每次读取20行。在第一次调用函数时,将读取从1到20的行,第二次调用它时,将读取21-40。

下面的简单代码在c ++中执行此操作,但我不知道如何在C#中实现它:

string readLines(ifstream& i)
{
     string totalLine="", line = "";
     for(int i = 0; i < 20; i++){
          getline(i, line);

          totalLine += line;
     }
     return totalLine;
}

int main()
{

     // ...
     ifstream in;
     in.open(filename.c_str());
     while(true){
         string next20 = readLines(in);
         // so something with 20 lines.
     }
     // ...

}

4 个答案:

答案 0 :(得分:3)

这里有各种选择,但一种简单的方法是:

using (var reader = File.OpenText("file.txt"))
{
    for (int i = 0; i < 25; i++)
    {
        HandleLines(reader);
    }
}

...

private void HandleLines(TextReader reader)
{
    for (int i = 0; i < 20; i++)
    {
        string line = reader.ReadLine();
        if (line != null) // Handle the file ending early
        {
            // Process the line
        }
    }
}

答案 1 :(得分:2)

如果尝试拨打LineRead() 最少次数并且您希望最小内存使用量,您可以先对文件中的行进行索引:

  
      
  1. 解析文件一次,索引 FileStream中每行的位置。
  2.   
  3. 仅在所需位置呼叫 ReadLine()
  4.   

例如:

// Parse the file
var indexes = new List<long>();
using (var fs = File.OpenRead("text.txt"))
{
    indexes.Add(fs.Position);
    int chr;
    while ((chr = fs.ReadByte()) != -1)
    {
        if (chr == '\n')
        {                        
            indexes.Add(fs.Position);
        }
    }
}

int minLine = 21;
int maxLine = 40;

// Read the line
using (var fs = File.OpenRead("text.txt"))
{
    for(int i = minLine ; i <= maxLine ; i++)
    {
        fs.Position = indexes[ i ];
        using (var sr = new StreamReader(fs))
            Console.WriteLine(sr.ReadLine());

}

干杯!

答案 2 :(得分:1)

您可以像这样编写Batch()方法:

public static IEnumerable<string> Batch(IEnumerable<string> input, int batchSize)
{
    int n = 0;
    var block = new StringBuilder();

    foreach (var line in input)
    {
        block.AppendLine(line);

        if (++n != batchSize)
            continue;

        yield return block.ToString();
        block.Clear();
        n = 0;
    }

    if (n != 0)
        yield return block.ToString();
}

并称之为:

string filename = "<Your filename goes here>";
var batches = Batch(File.ReadLines(filename), 20);

foreach (var block in batches)
{
    Console.Write(block);
    Console.WriteLine("------------------------");
}

答案 3 :(得分:0)

糟糕。 GroupBy不会懒惰地评估,所以这将贪婪地消耗整个文件

<击>

<击>
var twentyLineGroups = 
    File.ReadLines(somePath)
        .Select((line, index) => new {line, index})
        .GroupBy(x => x.index / 20)
        .Select(g => g.Select(x => x.line));

foreach(IEnumerable<string> twentyLineGroup in twentyLineGroups)
{
    foreach(string line in twentyLineGroup)
    {
        //tada!
    }
}

<击>