我有两个或多个日志文件将合并到一个新文件中。
日志文件格式可能类似于
Dir1 File1Path1 File1Path2 Timestamp tempfileName
Dir1 File2Path1 File2Path2 Timestamp tempfileName
Dir2 File1Path1 File1Path2 Timestamp tempfileName`
Dir3 File1Path1 File1Path2 Timestamp tempfileName
Dir3 File2Path1 File2Path2 Timestamp tempfileName
Dir3 File1Path1 File1Path2 Timestamp tempfileName
Dir4 File1Path1 File1Path2 Timestamp tempfileName`
等
我的要求如下;
我已经为1编写了代码。我读取文件并按行/列将内容加载到数据集中。
data.Tables[tableName].Columns.Add("Dir");
data.Tables[tableName].Columns.Add("Path1");
data.Tables[tableName].Columns.Add("Path2");
using (StreamReader reader = new StreamReader(log))
{
string line = string.Empty;
while ((line = reader.ReadLine()) != null)
{
data.Tables[tableName].Rows.Add(line.Split(new string[] { "\t" }, data.Tables[tableName].Columns.Count, StringSplitOptions.RemoveEmptyEntries));
}
}
但是要完成剩下的任务,我不确定是否将数据线加载到数据集中是对的?什么是最快和更好的方法?我可以遍历每一行值并比较休息,但我不认为它会更快。 日志文件可以在20 - 45MB之间。
合并的日志内容应该是这样的(行可以按任何顺序排列)
Dir1 File1Path1 File1Path2 Timestamp tempfileName
Dir1 File2Path1 File2Path2 Timestamp tempfileName
Dir2 File1Path1 File1Path2 Timestamp tempfileName
Dir4 File1Path1 File1Path2 Timestamp tempfileName
Dir3 File1Path1 File1Path2 Timestamp tempfileName
Dir3 File2Path1 File2Path2 Timestamp tempfileName
Dir3 File1Path1 File1Path2 Timestamp tempfileName
感谢您的光临。
答案 0 :(得分:1)
如果您可以一次将所有数据加载到内存中,那么检查重复项很容易:只需加载数据并让LINQ删除重复项。那就是:
List<string> lines = LoadEverything();
foreach (line in lines.Distinct()) // might want to supply an equality comparer
{
// write line to output file
}
如果无法一次加载内存中的所有文件,请加载每个文件,对其进行排序,然后将排序后的列表输出到新文件中。然后对已排序的文件执行n-way merge以删除重复项。
这些中的任何一个都比在任何重要大小的列表上使用List.Contains()
要快得多。
您没有说明是否要从每个单独的文件中删除重复项,或者是否要从组合文件中删除重复项。从单个文件中删除重复项很简单:只需将每个文件加载到内存中,对其执行Distinct
,然后将其写入输出。上面的讨论假定你想要从组合文件中删除重复项,如果你不能一次将所有内容加载到内存中,那就更难了。
如果你想要的只是确定是否有重复,以及那些重复是什么:
var dupes =
lines.GroupBy(l => l)
.Select(g => new { Value = g.Key, Count = g.Count() })
.Where(g => g.Count > 1);
foreach (var d in dupes)
{
Console.WriteLine("'{0}' is a dupe.", d.Key);
}
或者,如果您只想知道是否有重复项:
if (dupes.Any())
Console.WriteLine("There are duplicates!");