3

新しいファイルにマージされる 2 つ以上のログ ファイルがあります。

ログファイルの形式は次のようになります

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. 各ログ ファイルの各行の形式が正しいことを確認します。つまり、すべての値が記録されます。
  2. 重複がないことを確認する
  3. ファイルが正しくマージされていること、つまり、各ログ ファイルのすべてのログ行が新しいログ ファイルにマージされていることを確認します。
  4. 新しいマージされたファイルをベースライン ファイルと比較する

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

ご覧いただきありがとうございます。

4

1 に答える 1

2

一度にすべてのデータをメモリに読み込むことができれば、重複のチェックは簡単です。データを読み込んで、LINQ に重複を削除させるだけです。あれは:

List<string> lines = LoadEverything();
foreach (line in lines.Distinct()) // might want to supply an equality comparer
{
    // write line to output file
}

メモリ内のすべてのファイルを一度にロードできない場合は、1 つずつロードして並べ替え、並べ替えたリストを新しいファイルに出力します。次に、並べ替えられたファイルに対してn-way マージを実行して、重複を削除します。

List.Contains()これらのいずれも、かなりのサイズのリストで使用するよりもはるかに高速になります。

個々のファイルから重複を削除するかどうか、または結合されたファイルから重複を削除するかどうかについては言及しませんでした。個々のファイルから重複を削除するのは簡単です。各ファイルをメモリにロードし、Distinctそれに対して a を実行してから、出力に書き込むだけです。上記の説明は、結合されたファイルから重複を削除することを前提としています。一度にすべてをメモリにロードできない場合、これは少し難しくなります。

重複があるかどうか、およびそれらの重複が何であるかを判断することだけが必要な場合:

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!");
于 2013-09-10T19:40:41.863 に答える