【问题标题】:Finding all similar lines in a text file在文本文件中查找所有相似的行
【发布时间】:2026-01-27 14:50:01
【问题描述】:

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

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

【问题讨论】:

  • 你试过什么代码?您的预期输出是什么?
  • @SamLeach 我在问题的最后解释了我到目前为止所做的尝试。
  • 发布代码,以便我们了解您的需求。
  • 您是否必须使用 C# 来完成这项工作,或者它是一次性的任务,您可以使用其他工具来完成?
  • @MatthewStrawbridge 好吧,我在 C# 中这样做,所以这就是要走的路

标签: c# string file file-io


【解决方案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();
}

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

【讨论】:

    【解决方案2】:
    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
    }
    

    【讨论】:

    • 你可以只使用 line[0] 而不是拆分它
    • 假设初始字段只有 1char 宽。
    • 鉴于提问者特别提到了 CSV,最好尊重 CSV 中的 C 是逗号。
    • @Sayse:Ta。你会很高兴知道你的投票把我推到了 40k 大关,现在我可以回去工作了!
    • @Sayse No..wgat 如果号码是 2 位或更多位?!