0

I created checkboxes, where a user can set this for file searching:

  1. exclude system files: on/off
  2. exclude hidden files: on/off
  3. exclude read_only files: on/off

now I don't know, how I can use this three different boolean statements with this code line:

DirectoryInfo DirInfo = new DirectoryInfo(sCopyFilesFromFilePath);                    
GetDirsToCopy = 
   DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories).Where( ? );
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
StefanS
  • 211
  • 2
  • 3
  • 12

1 Answers1

2

You can use an implication. In logic a -> b is translated as !a || b, thus:

DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories)
       .Where(x => !excludeSystem || (x.Attributes&FileAttributes.System) == 0);
       .Where(x => !excludeHidden || (x.Attributes&FileAttributes.Hidden) == 0);
       .Where(x => !excludeReadOnly || (x.Attributes&FileAttributes.ReadOnly) == 0);

Here we assume excludeSystem, excludeHidden and excludeReadOnly are bools that you first fetched from the checkboxes.

You can of course write it in one Where as well.

Explanation (one .Where):

Given the following expression

x => !excludeSystem || (x.Attributes&FileAttributes.System) == 0

You can read this as a predicate. Say excludeSystem is false, then !excludeSystem is true, thus all directories will succeed. If not, the the second operand (x.Attributes&FileAttributes.System) == 0 is executed.

The second operand first does and bitwise & on the Attributes of x and the constant FileAttributes.System. If the Attributes thus contain FileAttributes.System, the result will be something different than zero. In that case the second test fails. In other words, you return false if the files are excluded and the file is a system-file.

Optimize

In case you think you will iterate over thousands of directories, you can make the code a bit more efficient, by making the tests faster:

IEnumerable<DirectoryInfo> temp = DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories);
if(excludeSystem) {
    temp = temp.Where((x.Attributes&FileAttributes.System) == 0);
}
if(excludeHidden) {
    temp = temp.Where((x.Attributes&FileAttributes.Hidden) == 0);
}
if(excludeReadOnly) {
    temp = temp.Where((x.Attributes&FileAttributes.ReadOnly) == 0);
}
GetDirsToCopy = temp;

This will (almost) always be efficient, but it makes the code a bit less beautiful.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Thank you. Do you know, how to exclude the folder "System Volume Information"? There is always an exception. – StefanS Jan 24 '15 at 18:55
  • @StefanS: what do you mean with exception? Can you give the stacktrace? – Willem Van Onsem Jan 24 '15 at 18:59
  • I am sorry, I was lazy yesterday. Every Windows root partition like C: or D: has a folder named "System Volume Information" and that folder is not detected by the linq code. I think this happens, because of "DirInfo.EnumerateDirectories". So I have to build a way around it. – StefanS Jan 25 '15 at 15:19