Sdílet prostřednictvím


Postupy: Porovnání obsahu dvou složek (LINQ)

Tento příklad ukazuje k porovnání dvou souborů výpisy třemi způsoby:

  • Pomocí dotazu na booleovskou hodnotu, která určuje, zda dvou souborů seznamů jsou identické.

  • Pomocí dotazu na průsečíku načíst soubory, které jsou v obou složkách.

  • Pomocí dotazu na sadu rozdíl načíst soubory, které jsou v jedné složce, ale ne na druhou.

    [!POZNÁMKA]

    Techniky zde uvedené mohou být přizpůsobeny porovnat sekvence objektů libovolného typu.

FileComparer Zde uvedená třída ukazuje, jak použít porovnávací nástroj vlastní třídu spolu s standardní operátory dotazu.Třída není určen pro použití ve skutečných situacích.Právě používá název a délka v bajtech každý soubor k určení, zda obsah každé složky jsou identické či nikoli.V případě skutečného světa upravte tento porovnávací nástroj provádět přísnější kontrolu rovnosti.

Příklad

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();
        }
    }
}

Probíhá kompilace kódu

  • Vytvoření Visual Studio projektu, který se zaměřuje.NET Framework verze 3.5.Ve výchozím nastavení projektu odkazuje na System.Core.dll a using směrnice (C#) nebo Imports prohlášení (Visual Basic) pro obor názvů System.Linq.V jazyce C# projekty, přidejte using směrnice pro obor názvů System.IO.

  • Zkopírujte kód do projektu.

  • Stisknutím klávesy F5 sestavit a spustit program.

  • Stisknutím libovolné klávesy uzavřete okno konzoly.

Robustní programování

Operace dotazu intenzivní nad obsah více typů dokumentů a souborů, zvažte použití Windows Desktop Search motoru.

Viz také

Koncepty

LINQ na objekty

LINQ a souborové adresáře