I'm enumerating all files in a directory so that I can process them later. I want to exclude hidden and system files.
This is what I have so far:
IEnumerable<IGrouping<string, string>> files;
files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories)
.Where(f => (new FileInfo(f).Attributes & FileAttributes.Hidden & FileAttributes.System) == 0)
.GroupBy(Path.GetDirectoryName);
However if I look at the results I am still getting hidden and system files included:
foreach (var folder in files)
{
foreach (var file in folder)
{
// value for file here still shows hidden/system file paths
}
}
I found this question which has a similar example from Jerome but I couldn't even get that to compile.
What am I doing wrong?
You can use
FileSystemInfo.Attributes.HasFlag
:You can simplify your code a lot by using DirectoryInfo and FileInfo, eg:
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 codeSince
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 be0
. So you’re essentially checking for the following: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:
You can also use
Enum.HasFlag
to make this a bit better understandable: