1

I'm trying to construct a parallel query using LINQ to get all of the text files and one CSV file in a certain directory and its subdirectories. I want to exclude hidden, temporary, and system files from even being considered by the query in hopes of speeding it up. (The directory is huge.) While I'm at it I also want to exclude a couple of the subdirectories. Here's my code:

ParallelQuery<string> getFiles =
    Directory.EnumerateFiles(@"C:\", "*", SearchOption.AllDirectories)
    .AsParallel().Where(f => (
        FileAttributes.Hidden == 0 &&
        FileAttributes.System == 0 &&
        FileAttributes.Temporary == 0 &&
        !Path.GetDirectoryName(f).Contains("TempDir") &&
        !Path.GetDirectoryName(f).Contains("OtherDir") &&
        (Path.GetExtension(f).ToUpper() == ".TXT" ||
        Path.GetFileName(f) == "GoodFile.csv")));

I tried to use the accepted answer to this question as a starting point. In Visual Studio (2013 Express Desktop, if it matters) I'm getting a green underline on the 7th-9th lines, the ones excluding certan subdirectories and restricting the results to .txt files, telling me Unreachable expression code detected. However, the line that includes the .csv file seems to been fine. Executing the query returns no results and does not throw any exceptions.

I'm still very, very new to LINQ so please forgive me if the issue here is blatantly obvious. Can anybody shed some light on this? Or perhaps there is a much better way of going about this?

Community
  • 1
  • 1
Alex A.
  • 5,466
  • 4
  • 26
  • 56

1 Answers1

6
FileAttributes.Hidden == 0 &&
FileAttributes.System == 0 &&
FileAttributes.Temporary == 0 &&

This is testing that the enumeration values are == 0, not if a file has that attribute. You need to create instances of System.IO.FileInfo to use FileInfo.Attributes. You can use .Select(f => new System.IO.FileInfo(f)) for this.

Jon B
  • 51,025
  • 31
  • 133
  • 161
  • More than that `FileAttributes.Hidden` is a constant enumeration value, not relevant to the file being processed by linq – drew_w Apr 30 '14 at 17:44
  • Thanks for your answer! If I use `f => new System.IO.FileInfo(f)` would I still be able to use `Path.GetExtension(f)`, etc? – Alex A. Apr 30 '14 at 17:46
  • Yes. Although `f` will now be a `FileInfo` instead of a `string`, so you'd use `f.Name`. – Jon B Apr 30 '14 at 17:47
  • When I use `.Select(f => new FileInfo(f))`, the query returns `FileInfo` objects rather than strings. How do I condition on attributes but return file paths as strings? – Alex A. Apr 30 '14 at 17:55
  • 1
    @Alex - you can use the `.Name` property instead, add a `Select(f => f.Name)` at the end, or - and this is what I would do - factor out the logic into a separate function that takes in a string and returns a bool - so it would be `.Where(f => UseThisFile(f))`. – Jon B Apr 30 '14 at 18:01