2 つのフォルダーの内容を比較する方法 (LINQ) (C#)How to compare the contents of two folders (LINQ) (C#)

この例では、2 つのファイル リストを比較する 3 つの方法を示します。This example demonstrates three ways to compare two file listings:

  • 2 つのファイル リストが同一であるかどうかを指定するブール値をクエリする方法By querying for a Boolean value that specifies whether the two file lists are identical.

  • 両方のフォルダー内にあるファイルを取得するために、共通部分をクエリする方法By querying for the intersection to retrieve the files that are in both folders.

  • 1 つのフォルダーにあり、もう 1 つのフォルダーにはないファイルを取得するために、差集合をクエリする方法By querying for the set difference to retrieve the files that are in one folder but not the other.

    注意

    ここに示す方法は、任意の型のオブジェクトのシーケンスを比較するために適用させることができます。The techniques shown here can be adapted to compare sequences of objects of any type.

ここに示す FileComparer クラスは、標準クエリ演算子と共に、カスタム比較演算子クラスを使用する方法を示します。The FileComparer class shown here demonstrates how to use a custom comparer class together with the Standard Query Operators. このクラスは、実際のシナリオで使用することは想定されていません。The class is not intended for use in real-world scenarios. 各フォルダーの内容が同一であるかどうかを判断するために、各ファイルの名前と長さ (バイト) を使用するだけです。It just uses the name and length in bytes of each file to determine whether the contents of each folder are identical or not. 実際のシナリオでは、この比較演算子を変更して、より厳密に等しいかどうかをチェックします。In a real-world scenario, you should modify this comparer to perform a more rigorous equality check.

Example

namespace QueryCompareTwoDirs  
{  
    class CompareDirs  
    {  
  
        static void Main(string[] args)  
        {  
  
            // Create two identical or different temporary folders
            // on a local drive and change these file paths.  
            string pathA = @"C:\TestDir";  
            string pathB = @"C:\TestDir2";  
  
            System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);  
            System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);  
  
            // Take a snapshot of the file system.  
            IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories);  
            IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories);  
  
            //A custom file comparer defined below  
            FileCompare myFileCompare = new FileCompare();  
  
            // This query determines whether the two folders contain  
            // identical file lists, based on the custom file comparer  
            // that is defined in the FileCompare class.  
            // The query executes immediately because it returns a bool.  
            bool areIdentical = list1.SequenceEqual(list2, myFileCompare);  
  
            if (areIdentical == true)  
            {  
                Console.WriteLine("the two folders are the same");  
            }  
            else  
            {  
                Console.WriteLine("The two folders are not the same");  
            }  
  
            // Find the common files. It produces a sequence and doesn't
            // execute until the foreach statement.  
            var queryCommonFiles = list1.Intersect(list2, myFileCompare);  
  
            if (queryCommonFiles.Any())  
            {  
                Console.WriteLine("The following files are in both folders:");  
                foreach (var v in queryCommonFiles)  
                {  
                    Console.WriteLine(v.FullName); //shows which items end up in result list  
                }  
            }  
            else  
            {  
                Console.WriteLine("There are no common files in the two folders.");  
            }  
  
            // Find the set difference between the two folders.  
            // For this example we only check one way.  
            var queryList1Only = (from file in list1  
                                  select file).Except(list2, myFileCompare);  
  
            Console.WriteLine("The following files are in list1 but not list2:");  
            foreach (var v in queryList1Only)  
            {  
                Console.WriteLine(v.FullName);  
            }  
  
            // Keep the console window open in debug mode.  
            Console.WriteLine("Press any key to exit.");  
            Console.ReadKey();  
        }  
    }  
  
    // This implementation defines a very simple comparison  
    // between two FileInfo objects. It only compares the name  
    // of the files being compared and their length in bytes.  
    class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>  
    {  
        public FileCompare() { }  
  
        public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)  
        {  
            return (f1.Name == f2.Name &&  
                    f1.Length == f2.Length);  
        }  
  
        // Return a hash that reflects the comparison criteria. According to the
        // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must  
        // also be equal. Because equality as defined here is a simple value equality, not  
        // reference identity, it is possible that two or more objects will produce the same  
        // hash code.  
        public int GetHashCode(System.IO.FileInfo fi)  
        {  
            string s = $"{fi.Name}{fi.Length}";
            return s.GetHashCode();  
        }  
    }  
}  

コードのコンパイルCompiling the Code

System.Linq 名前空間と System.IO 名前空間に using ディレクティブを使用して、C# コンソール アプリケーション プロジェクトを作成します。Create a C# console application project, with using directives for the System.Linq and System.IO namespaces.

関連項目See also