How to use Directory.EnumerateFiles excluding hidden and system files
.Where(f => (new FileInfo(f).Attributes & FileAttributes.Hidden & FileAttributes.System) == 0)
Since FileAttributes
values are flags, they are disjunctive on the bit level, so you can combine them properly. As such, FileAttributes.Hidden & FileAttributes.System
will always be 0
. So you’re essentially checking for the following:
(new FileInfo(f).Attributes & 0) == 0
And that will always be true since you are removing any value with the & 0
part.
What you want to check is whether the file has neither of those flags, or in other words, if there are no common flags with the combination of both:
.Where(f => (new FileInfo(f).Attributes & (FileAttributes.Hidden | FileAttributes.System)) == 0)
You can also use Enum.HasFlag
to make this a bit better understandable:
.Where(f => !new FileInfo(f).Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System))
You can simplify your code a lot by using DirectoryInfo and FileInfo, eg:
var mask= FileAttributes.Hidden | FileAttributes.System;
var di=new DirectoryInfo(sourcePath);
var files=di.EnumerateFiles("*", SearchOption.AllDirectories)
.Where(fi=>(fi.Attributes & mask) == 0)
.GroupBy(fi=>fi.DirectoryName);
Your original code tried to do a bitwise AND between flags that had no common bits, so it returned 0. As a result, the bitwise AND with Attributes
also returned 0.
The mask you want to check against is System or Hidden ie FileAttributes.Hidden | FileAttributes.System
. Calculating this in advance simply makes for somewhat cleaner code