查找文本文件中的所有相似行

时间:2013-06-12 12:18:12

标签: c# string file file-io

我有一个包含逗号分隔值的文本文件。它看起来像这样:

3,23500,R,5998,20.38,06/12/2013 01:44:17
2,23500,P,5983,20.234,06/12/2013 01:44:17
3,23501,R,5998,20.38,06/12/2013 01:44:18
2,23501,P,5983,20.235,06/12/2013 01:44:18
3,23502,R,6000,20.4,06/12/2013 01:44:19
2,23502,P,5983,20.236,06/12/2013 01:44:19
3,23503,R,5999,20.39,06/12/2013 01:44:20
2,23503,P,5983,20.236,06/12/2013 01:44:20

我的任务是从唯一文件中提取以相同数字开头的行。例如,在上面的例子中,您会看到一些行以2开头,一些行以3开头......可能会有更多案例,例如4等......

这样做的最佳和最好的方法是什么?我正在使用的文件非常大,有时大小为千兆字节......

我确实拆分了每一行并存储了第一个值,这个值将是我在数组中查找的数字,然后从数组中删除重复的值......它可以工作,但速度非常慢!

这是我自己的代码:

private void buttonBeginProcess_Click(object sender, EventArgs e)
{
    var file = File.ReadAllLines(_fileName);
    var nodeId = new List<int>();

    foreach (var line in file)
    {
        nodeId.Add(int.Parse(line.Split(',')[0]));
    }

    //Unique numbers
    nodeId = nodeId.Distinct().ToList();
}

2 个答案:

答案 0 :(得分:3)

var lines = File.ReadLines(myFilePath);
var lineGroups = lines
                  .Where(line => line.Contains(","))
                  .Select(line => new{key = line.Split(',')[0], line})
                  .GroupBy(x => x.key);
foreach(var lineGroup in lineGroups)
{
    var key = lineGroup.Key;
    var keySpecificLines = lineGroup.Select(x => x.line);
    //save keySpecificLines to file
}

答案 1 :(得分:1)

您可以尝试使用StreamReader / StreamWriter一次处理一行文件:

var writers = new Dictionary<string, StreamWriter>();

using (StreamReader sr = new StreamReader(pathToFile)) 
{
    while (sr.Peek() >= 0) 
    {
        var line = sr.ReadLine();
        var key = line.Split(new[]{ ',' },2)[0];
        if (!lineGroups.ContainsKey(key))
        {
            writers[key] = new StreamWriter(GetPathToOutput(key));
        }

        writers[key].WriteLine(line);
    }
}

foreach(StreamWriter sw in writers.Values)
{
    sw.Dispose();
}

使用此方法,您可以确保代码永远不必使用整个输入文件,因此输入文件的大小无关紧要。当然,缺点是它必须在整个过程中保持任意数量的文件打开。