Udostępnij za pośrednictwem


Porady: porównywanie zawartości dwóch folderów (LINQ)

Ten przykład demonstruje porównywanie dwóch plików aukcje na trzy sposoby:

  • Za pomocą kwerend wysyłanych na wartość logiczną, która określa, czy plik dwie listy są identyczne.

  • Za pomocą kwerend wysyłanych do przecięcia pobrać pliki, które są w obu folderach.

  • Przez odpytywanie różnica zestawu do pobierania plików, które znajdują się w jednym folderze, ale nie dla drugiego.

    [!UWAGA]

    Techniki, o których tu można dostosować do porównania sekwencji obiektów dowolnego typu.

FileComparer Przedstawionej tutaj klasie przedstawiono sposób użycia klasy niestandardowy moduł porównujący wraz z standardowe operatory kwerendy.Klasa nie jest przeznaczony do użycia w scenariuszach rzeczywistych.Po prostu używa nazwy i długości w bajtach każdego pliku do ustalenia, czy zawartość każdego folderu są identyczne.W scenariuszu świata rzeczywistego należy zmodyfikować tego modułu porównującego do wykonania bardziej rygorystyczną kontrolę równości.

Przykład

Module CompareDirs
    Public Sub Main()


        ' Create two identical or different temporary folders  
        ' on a local drive and add files to them. 
        ' Then set these file paths accordingly. 
        Dim pathA As String = "C:\TestDir" 
        Dim pathB As String = "C:\TestDir2" 

        ' Take a snapshot of the file system.  
        Dim dir1 As New System.IO.DirectoryInfo(pathA)
        Dim dir2 As New System.IO.DirectoryInfo(pathB)

        Dim list1 = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories)
        Dim list2 = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories)

        ' Create the FileCompare object we'll use in each query 
        Dim myFileCompare As 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. 
        Dim areIdentical As Boolean = list1.SequenceEqual(list2, myFileCompare)
        If areIdentical = True Then
            Console.WriteLine("The two folders are the same.")
        Else
            Console.WriteLine("The two folders are not the same.")
        End If 

        ' Find common files in both folders. It produces a sequence and doesn't execute 
        ' until the foreach statement. 
        Dim queryCommonFiles = list1.Intersect(list2, myFileCompare)

        If queryCommonFiles.Count() > 0 Then


            Console.WriteLine("The following files are in both folders:")
            For Each fi As System.IO.FileInfo In queryCommonFiles
                Console.WriteLine(fi.FullName)
            Next 
        Else
            Console.WriteLine("There are no common files in the two folders.")
        End If 

        ' Find the set difference between the two folders. 
        ' For this example we only check one way. 
        Dim queryDirAOnly = list1.Except(list2, myFileCompare)
        Console.WriteLine("The following files are in dirA but not dirB:")
        For Each fi As System.IO.FileInfo In queryDirAOnly
            Console.WriteLine(fi.FullName)
        Next 

        ' Keep the console window open in debug mode
        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()
    End Sub 

    ' 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. 
    Public Class FileCompare
        Implements System.Collections.Generic.IEqualityComparer(Of System.IO.FileInfo)

        Public Function Equals1(ByVal x As System.IO.FileInfo, ByVal y As System.IO.FileInfo) _
            As Boolean Implements System.Collections.Generic.IEqualityComparer(Of System.IO.FileInfo).Equals

            If (x.Name = y.Name) And (x.Length = y.Length) Then 
                Return True 
            Else 
                Return False 
            End If 
        End Function 

        ' Return a hash that reflects the comparison criteria. According to the  
        ' rules for IEqualityComparer(Of 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 Function GetHashCode1(ByVal fi As System.IO.FileInfo) _
            As Integer Implements System.Collections.Generic.IEqualityComparer(Of System.IO.FileInfo).GetHashCode
            Dim s As String = fi.Name & fi.Length
            Return s.GetHashCode()
        End Function 
    End Class 
End Module
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.Count() > 0)
            {
                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 = String.Format("{0}{1}", fi.Name, fi.Length);
            return s.GetHashCode();
        }
    }
}

Kompilowanie kodu

  • Tworzenie Visual Studio projekt, który jest przeznaczony.NET Framework w wersji 3.5.Domyślnie projekt zawiera odwołanie do System.Core.dll i using dyrektywy (C#) lub Imports instrukcji (Visual Basic) dla nazw System.Linq.W języku C# projektów, należy dodać using dyrektywa obszaru nazw System.IO.

  • Skopiuj kod do projektu.

  • Naciśnij klawisz F5, aby skompilować i uruchomić program.

  • Naciśnij dowolny klawisz, aby zamknąć okno konsoli.

Stabilne programowanie

Kwerendy intensywnych operacji nad zawartość wielu rodzajów dokumentów i plików, należy rozważyć użycie Wyszukiwanie z pulpitu systemu Windows silnika.

Zobacz też

Koncepcje

LINQ do obiektów

LINQ i katalogi plików