none
Comparing contents of a folder with the root of a USB storage device using LINQ RRS feed

  • Question

  • Hi all,

    I have written an application that does the following:

    1. Detects when a USB storage device is plugged in
    2. Compares the contents of the USB storage device against a reference folder's contents
    3. Copies files from the reference folder onto the USB storage device if the two aren't identical

    I am using the example from the following link:
    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/how-to-compare-the-contents-of-two-folders-linq

    The issue that I have run into is that the root of a USB storage device will have two extraneous files, "IndexerVolumeGuid", and "WPSettings.dat", which causes the two IEnumerable<System.IO.FileInfo> lists to be different even when the reference folder and USB drive are otherwise identical.

    I have tried to rectify this by generating a new list Where(file => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid"), but in comparing the two lists, the order has still changed as a result of the two files, resulting yet again in the lists being unidentical.

    Can anyone point me in the right direction so as to be able to compare the reference folder with the root of a USB drive?

    My code is below:

    private bool areFoldersIdentical(string referencePath, string USBRoot)
    {
    	System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(referencePath, );
    	System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(USBRoot);
    
    	// 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);
    
    	list1 = list1.Where(name => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();
    	list2 = list2.Where(name => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();
    
    	//A custom file comparer defined from example in the given link
    	FileCompare myFileCompare = new FileCompare();
    
    	bool areIdentical = list1.SequenceEqual(list2, myFileCompare);
    
    	if (areIdentical == true)
    	{
    		Console.WriteLine("the two folders are the same");
    		return true;
    	}
    	else
    	{
    		Console.WriteLine("The two folders are not the same");
    		return false;
    	}
    }

    Thanks in advance!

    -- Thomas


    Thursday, June 14, 2018 10:07 AM

All replies

  • "the order has still changed as a result of the two files, resulting yet again in the lists being unidentical."

    The order of directories/files on disk is never guaranteed. The order is going to be whatever order the file system returns so you shouldn't make any assumptions about ordering unless you explicitly have an OrderBy clause.

    To determine if 2 directories are equal you'd need to basically intersect/except the results. This would produce the set of items that are missing from one or the other. Order doesn't matter.

    Couple of ways to do it. Firstly you could add an order by to each of the lists before comparing to force them to sort by filename. Alternatively consider using Except to find the differences. Unfortunately you'd have to call this twice to find the missing elements from the first and then missing elements from the second. If you don't actually care about the differences then if the method returns anything they are different. Just be sure to compare them by filename or something and not reference as that wouldn't work.

    Another approach would be to use Intersect. This returns the intersection of the 2 sequences. If you get back more items then in either list then they don't match either. This is faster than except if you only want to know if they are different.

    AFAIK LINQ doesn't have a "Differences" method but someone might have written one. It wouldn't be too hard and would involve enumerating the items in the first list and comparing them to the second. 


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, June 14, 2018 2:12 PM
    Moderator
  • To be precise, those files (WPSettings.dat and "IndexerVolumeGuid") are NOT in "the root of a USB storage device".  They are inside the "System Volume Information" folder, which is normally hidden and protected from access.  You probably want to ignore anything inside that folder.

    Tim Roberts, Driver MVP Providenza & Boekelheide, Inc.

    Thursday, June 14, 2018 11:20 PM
  • Hi Thomas,

    From your description, you mention that you use Where(file => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid") to generate a new list. However, in the codes you provided,the statements below are different from you mentioned previously, which cannot be compiled. 

    list1 = list1.Where(name => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();
    list2 = list2.Where(name => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();
    

    When I modify the two statements as below, the two lists are identical. Please check this.

     list1 = list1.Where(file => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();
     list2 = list2.Where(file => file.Name != "WPSettings.dat" && file.Name != "IndexerVolumeGuid").ToList();

    Regards,

    Dolen


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, June 15, 2018 8:52 AM