none
Extracting specific information from IEnumerable using LINQ? RRS feed

  • Question

  • Hi

    I have an IEnumerable which contains file and directory information - example below of its contents:-

    I want to extract specific information from this IEnumerable and am assuming LINQ is the best route

    I want a list of files and a separate list of directories in a given path - but just that level, so not including sub directories etc

    The lists just need to contain the FullName of each file / directory and nothing else

    The Attributes value contains Directory if a directory so I can use that to easily determine if a file or a directory using something similar to below

    Dim dirs2 = nodes.Where(Function(n) n.FullName.StartsWith(path) And n.Attributes = Attributes.Directory)
    Dim files2 = nodes.Where(Function(n) n.FullName.StartsWith(path) And n.Attributes <> Attributes.Directory)

    But I am stuck on how I just return the FullName value - AND - how to just return one level

    Example project linked below shows exactly how the IEnumerable is filled using NTFSreader link

    N.B. I want to continue using Ntfs reader and NOT use IO.Directory.GetDirectories / GetFiles as NTFS reader is much quicker and doesn't have same issue with permissions as it gets information directly from MFT


    Anyone here got any thoughts please?


    Darren Rose



    • Edited by wingers Saturday, November 21, 2020 9:00 PM
    Saturday, November 21, 2020 1:36 PM

Answers

  • Problem solved

    Dim dirs As List(Of String) = nodes.Where(Function(n)
             Return n.FullName = path & n.Name AndAlso ((n.Attributes And Attributes.Directory) = Attributes.Directory)
             End Function).Select(Function(n) n.FullName).OrderBy(Function(n) n).ToList
    
    
    Dim files As List(Of String) = nodes.Where(Function(n)
              Return n.FullName = path & n.Name AndAlso ((n.Attributes And Attributes.Directory) <> Attributes.Directory)
              End Function).Select(Function(n) n.FullName).OrderBy(Function(n) n).ToList

    and need to ensure "path" has a trailing \ e.g. C:\ or C:\Windows\ and NOT C:\Windows as if not won't work

    All input appreciated :)


    Darren Rose


    • Edited by wingers Sunday, November 22, 2020 5:42 PM
    • Marked as answer by wingers Sunday, November 22, 2020 5:42 PM
    Sunday, November 22, 2020 5:42 PM

All replies

  • Hi

    Please show how you fill the IEnumerable as the 'see below' doesn't show that.


    Regards Les, Livingston, Scotland

    Saturday, November 21, 2020 1:54 PM
  • Example project linked below shows exactly how the IEnumerable is filled using NTFSreader

    http://www.pcassistonline.co.uk/upload/test_source.zip

    Missing image also added to original post


    Darren Rose


    • Edited by wingers Saturday, November 21, 2020 5:31 PM
    Saturday, November 21, 2020 2:09 PM
  • Check this out, a work in progress working on C:\Users for *.dll

    https://github.com/karenpayneoregon/visual-basic-getting-started/blob/master/RecurseFolders/OtherExamplesForm.vb

    See also

    https://github.com/karenpayneoregon/visual-basic-getting-started/blob/master/FileHelpers/Operations.vb#L125

    Note these code samples do not match up completely to your requirements but see if they can be adjusted to your needs.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    My GitHub code samples
    GitHub page

    Saturday, November 21, 2020 2:18 PM
    Moderator
  • Hi,

    to select specific information from a linq query use the Select method:

    Dim dirs2 = nodes
        .Where(Function(n) n.FullName.StartsWith(path) And n.Attributes = Attributes.Directory)
        .Select(Function(d) d.FullName)
    

    best regards.

    Sunday, November 22, 2020 1:51 PM
  • Hi,

    to select specific information from a linq query use the Select method:

    Dim dirs2 = nodes
        .Where(Function(n) n.FullName.StartsWith(path) And n.Attributes = Attributes.Directory)
        .Select(Function(d) d.FullName)

    best regards.

    Thanks, but that will get all files / directories which start with given path e.g. C:\Windows would also give all folders and subfolders in C:\Windows, and I specifically stated I only want ONE level e.g. just files/folders in ROOT of given path

    So to make it clear

    If I had file layout as below

    C:\
    C:\doc.txt
    C:\Folder1
    C:\Folder2
    C:\Folder2\Folder3
    C:\Folder2\me.txt
    C:\Folder2\Folder3\me2.txt

    If I provided path of C:\ then it would return C:\doc.txt C:\Folder1 and C:\Folder2

    If I provided path of C:\Folder2 then it would return C:\Folder2\Folder3 and C:\Folder2\me.txt

    If I provided path of C:\Folder2\Folder3 then it would return C:\Folder2\Folder3\me2.txt

    So basically just giving me folders and files in the ROOT of the given path


    Darren Rose



    • Edited by wingers Sunday, November 22, 2020 2:06 PM
    Sunday, November 22, 2020 1:56 PM
  • Okey, 

    lets use more appropriate solution to get directories enumerable which consist of using the EnumerateFolder(SearchOptions) method overload:

    Dim dirPath = "tour dir path"
    Dim diTop As DirectoryInfo = new DirectoryInfo(dirPath)
    diTop.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
    
    diTop.Select(Function(d) d.FullName)

    take a look to this article about using SearchOption:

    https://docs.microsoft.com/en-us/dotnet/api/system.io.searchoption?view=net-5.0#System_IO_SearchOption_TopDirectoryOnly

    Sunday, November 22, 2020 2:13 PM
  • As per original post:-

    "N.B. I want to continue using Ntfs reader and NOT use IO.Directory.GetDirectories / GetFiles etc as NTFS reader is much quicker and doesn't have same issue with IO permissions as it gets information directly from MFT"

    It is also very much quicker, getting information on ALL on my C: drive in just over 3 seconds.

    "628.307 MB of volume metadata has been read in 3.086 s at 203.579 MB/s
    599600 nodes have been retrieved in 683.7102 ms"


    Darren Rose

    Sunday, November 22, 2020 2:16 PM
  • Problem solved

    Dim dirs As List(Of String) = nodes.Where(Function(n)
             Return n.FullName = path & n.Name AndAlso ((n.Attributes And Attributes.Directory) = Attributes.Directory)
             End Function).Select(Function(n) n.FullName).OrderBy(Function(n) n).ToList
    
    
    Dim files As List(Of String) = nodes.Where(Function(n)
              Return n.FullName = path & n.Name AndAlso ((n.Attributes And Attributes.Directory) <> Attributes.Directory)
              End Function).Select(Function(n) n.FullName).OrderBy(Function(n) n).ToList

    and need to ensure "path" has a trailing \ e.g. C:\ or C:\Windows\ and NOT C:\Windows as if not won't work

    All input appreciated :)


    Darren Rose


    • Edited by wingers Sunday, November 22, 2020 5:42 PM
    • Marked as answer by wingers Sunday, November 22, 2020 5:42 PM
    Sunday, November 22, 2020 5:42 PM
  • Hi

    I recreated the code using your link and from this thread -  as best as I could.

    Here are some timings I got.


    Regards Les, Livingston, Scotland

    Sunday, November 22, 2020 7:04 PM
  • Okay cool

    I hadn't actually timed getting the dirs and files, the output I posted was just what ntfsreader shows in console when getting all files on my C: drive e.g.

    628.759 MB of volume metadata has been read in 2.902 s at 216.635 MB/s
    599379 nodes have been retrieved in 656.6876 ms


    Darren Rose

    Sunday, November 22, 2020 7:06 PM