Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Directory.EnumerateFiles excluding hidden and system files

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?

like image 358
Equalsk Avatar asked Jan 05 '16 11:01

Equalsk


1 Answers

.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))
like image 91
poke Avatar answered Oct 14 '22 18:10

poke