【问题标题】:C# Merging Two or more Text Files side by sideC#并排合并两个或多个文本文件
【发布时间】:2018-11-08 04:32:19
【问题描述】:
using (StreamWriter writer = File.CreateText(FinishedFile))
{
    int lineNum = 0;
    while (lineNum < FilesLineCount.Min())
    {
        for (int i = 0; i <= FilesToMerge.Count() - 1; i++)
        {
            if (i != FilesToMerge.Count() - 1)
            {
                var CurrentFile = File.ReadLines(FilesToMerge[i]).Skip(lineNum).Take(1);
                string CurrentLine = string.Join("", CurrentFile);
                writer.Write(CurrentLine + ",");
            }
            else
            {
                var CurrentFile = File.ReadLines(FilesToMerge[i]).Skip(lineNum).Take(1);
                string CurrentLine = string.Join("", CurrentFile);
                writer.Write(CurrentLine + "\n");
            }
        }
        lineNum++;
    }
}

我目前这样做的方式太慢了。我正在合并每个 50k+ 行长的文件和不同数量的数据。

例如: 文件 1
1
2
3
4

文件 2
4
3
2
1

我需要将其合并为第三个文件
文件 3
1,4
2,3
3,2
4,1

附言用户可以从任何位置选择任意数量的文件。
感谢您的帮助。

【问题讨论】:

  • 您的代码和您的问题陈述似乎不像我预期的那样匹配。您是否有恰好两个文件(File1 和 File2)并且您正在尝试将每个文件的组合添加到一个新文件(File3)?组合逻辑(伪代码)为:file3[i] = file1[i] + "," + file2[i]
  • 在每次迭代中,您都会再次读取整个文件,您应该在每次迭代中逐行读取它们
  • @maccettura 这是任意数量的文件,它们都转到文件 3,我最后补充说,也许我的逻辑是问题,任何帮助都值得赞赏。我当前的代码正确地合并了它们,对于我使用的文件大小来说非常慢。
  • 您的文件长度/行数是否相同?
  • @AdamStrobel 我看到了你最后写的东西,但它仍然没有意义。用户是否能够选择任何 两个 文件的路径?还是允许他们选择无限个文件的路径?

标签: c# performance merge


【解决方案1】:

由于循环中的Skip 和Take,您的方法很慢。

您可以使用字典来收集所有行索引的行:

string[] allFileLocationsToMerge = { "filepath1", "filepath2", "..." };
var mergedLists = new Dictionary<int, List<string>>();
foreach (string file in allFileLocationsToMerge)
{
    string[] allLines = File.ReadAllLines(file);
    for (int lineIndex = 0; lineIndex < allLines.Length; lineIndex++)
    {
        bool indexKnown = mergedLists.TryGetValue(lineIndex, out List<string> allLinesAtIndex);
        if (!indexKnown)
            allLinesAtIndex = new List<string>();
        allLinesAtIndex.Add(allLines[lineIndex]);
        mergedLists[lineIndex] = allLinesAtIndex;
    }
}

IEnumerable<string> mergeLines = mergedLists.Values.Select(list => string.Join(",", list));
File.WriteAllLines("targetPath", mergeLines);

【讨论】:

  • 谢谢,这速度要快得多,我不知道跳过和拍摄会慢得多。谢谢!
【解决方案2】:

这是另一种方法 - 此实现仅在内存中同时存储来自每个文件的一组行,从而显着降低内存压力(如果这是一个问题)。

public static void MergeFiles(string output, params string[] inputs)
{
    var files = inputs.Select(File.ReadLines).Select(iter => iter.GetEnumerator()).ToArray();
    StringBuilder line = new StringBuilder();
    bool any;

    using (var outFile = File.CreateText(output))
    {
        do
        {
            line.Clear();
            any = false;

            foreach (var iter in files)
            {
                if (!iter.MoveNext())
                    continue;

                if (line.Length != 0)
                    line.Append(", ");

                line.Append(iter.Current);
                any = true;
            }

            if (any)
                outFile.WriteLine(line.ToString());
        }
        while (any);
    }

    foreach (var iter in files)
    {
        iter.Dispose();
    }
}

这也处理不同长度的文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    相关资源
    最近更新 更多