【问题标题】:Split text file every 120,000 Lines?每 120,000 行拆分文本文件?
【发布时间】:2014-02-17 18:47:44
【问题描述】:

所以我有一个文本文件,我需要每 120,000 行拆分一次,当它在第 120,000 行拆分时,我需要将其余部分拆分到另一个文本文件中。对这家伙有什么想法吗?

【问题讨论】:

  • 是的,很容易。逐行读取并在计数器为该数字时保持计数器,写入新文件。
  • 到目前为止你做了什么?提供您的代码,然后我们可以提供帮助:)
  • 使用File.ReadLines 和一个计数器。

标签: c# .net text


【解决方案1】:

您可以使用Batch from MoreLINQ 将您的行分组为 120,000 行的批次,然后每个批次可以单独处理。

foreach(var batch in File.ReadLines(inputFile).Batch(120000))
    WriteToFile(batch);

【讨论】:

    【解决方案2】:
    var lines = new List<string>();
    int counter = 0,i = 1;
    string line;
    using (var reader = new StreamReader("filePath"))
    {
       while ((line = reader.ReadLine()) != null)
       {
              lines.Add(line);
              counter++;
              if (counter == 120000)
              {
                  string fileName = String.Format("file{0}.txt",i);
                  File.WriteAllLines(fileName,lines);
                  lines.Clear();
                  counter = 0;
                  i++;
              }
        }
    }
    if(lines.Count > 0) File.WriteAllLines("path", lines);
    

    注意:使用File.WriteAllLines 时应使用不同的文件名,否则只会覆盖单个文件的内容。例如,您可以为其使用另一个计数器并为每个文件递增它,"file1, file2 etc.."

    【讨论】:

    • -1,最终会一次又一次地写入同一个文件
    • @NewHire OP 应该更改文件路径。显然他可以弄清楚(至少!)?
    • @NewHire,这很容易解决,恕我直言,不应该投反对票。
    • 有什么理由使用StreamReader 而不是File.ReadLines 方法?
    • @Default 可以使用,但不是必须的。File.ReadLines 仍在使用StreamReader...不过我觉得这种方式更直接
    【解决方案3】:

    使用Enumerable.GroupBy 和“整数除法组”的另一种方式:

    int batchSize = 120000;
    var fileGroups = File.ReadLines(path)
        .Select((line, index) => new { line, index })
        .GroupBy(x => x.index / batchSize)
        .Select((group, index) => new {
            Path = Path.Combine(dir, string.Format("FileName_{0}.txt", index + 1)),
            Lines = group.Select(x => x.line)
        });
    foreach (var file in fileGroups)
        File.WriteAllLines(file.Path, file.Lines);
    

    【讨论】:

    • 并且可读性是通过屋顶! :) 我实际上想到了一个类似的答案,使用 Select 和 GroupBy 以及 Func 作为文件名,隐藏在一个方法中 - 但它只是.. 所以.. 可怕.. :s 它确实没有显示出漂亮的一面LINQ(Servys 的回答至少有点隐藏)。顺便说一句..我没有发布的另一个原因是我不确定性能提升。 Servys 回答加载 12000 个实体(通过存储桶) - 你知道这是否更好,因为它都是 IEnumerables 和 IGroupings(我猜是产量),即它会表现更好吗?
    • @Default: 你说得对!如果索引发挥作用,LINQ 通常不是正确的工具。我只展示了该方法 1. 它相对较短,2. 不需要第三方库/代码,以及 3. 你使用的次数越多,它的可读性就越高;)
    • @默认值:acc。对于性能,我认为 morelinq 更有效。