Currently there is no support for using multiple regex filters to monitor the file system using FileSystemWatcher Class. eg. If we want to monitor files with two extensions (.dll and .pdb), we wont be able to directly to due it.
There are 2 ways to work around this issue but non of them is optimal.
"*" filter and then prune the files manually in the event handler.eg. If (filename.endswith("*.txt") || filename.endswith("*.csv"))
// do
This approach is highly inefficient because first of all we are listening to all files and then user have to manually filter the files which defeats the purpose of having the Filter in the first place. Here are some links where people asked for this new functionality but has to settle down for this approach
https://stackoverflow.com/questions/6965184/how-to-set-filter-for-filesystemwatcher-for-multiple-file-types
https://social.msdn.microsoft.com/Forums/vstudio/en-US/91ebc868-2661-4477-b825-5b796d020ab1/how-do-i-setup-filewatcher-filter-for-multiple-document-types?forum=csharpgeneral
https://stackoverflow.com/questions/38467389/filter-to-not-include-multiple-extensions
``` C#
namespace System.IO
{
public class FileSystemWatcher
{
public Collection
}
}
Currently we use ```string _filter``` as a backing field for ```Filter``` property. I suggest using ```Collection<string> _filterList``` as a backing field for both the ```Filter and FilterList Property```.
Filter property will always return the first element of the list (In Case of multiple Filters too)
# Implementation Branch
https://github.com/Anipik/corefx/tree/Filter
This is the rough implementation of the api and how it will modify the ```constructor and Filter property```.
>what happens when you set Filter?
It just sets the first element and does not reduce the size of collection.
>What happens if you set FilterList to null or empty or clear it or removeall items using removeAt?
In all the above cases, we change it to the collection with just only one element i.e ```*```
>What do we do if an element in Filters is null or empty? If we match everything, can/should we optimize?
We never have a ```null or empty element``` in the collection. We always replace it with ```*``` while adding to the collection
>If we match everything, can/should we optimize?
We can optimise by not going further through the collection of the list if we encounter ```*```.
>What about a constructor overload that takes the filters?
we can use Initializer to initialize the FilterList
var watcher3 = new FileSystemWatcher() { FilterList = new Collection
Assert.Equal(3, watcher3.FilterList.Count);
It will be breaking change as ```FileSystemWatcher("path", null)``` will be ambiguous call for ```FileSystemWater(string path, IEnumnerable<string> FilterList)```
# Usage
``` C#
var watcher = new FileSystemWatcher();
watcher.FilterList[0] = "*.pdb";
watcher.FilterList.Add("*.exe");
watcher.FilterList.Add("*.dll");
Assert.Equal(3, watcher.FilterList.Count);
var watcher2 = new FileSystemWatcher( @"C:\git\corefx","*.pdb");
watcher2.FilterList.Add("*.exe");
watcher2.FilterList.Add("*.dll");
Assert.Equal(3, watcher2.FilterList.Count);
var watcher3 = new FileSystemWatcher() { FilterList = new Collection<string> { "*.pdb", ".exe", ".doc" } };
Assert.Equal(3, watcher3.FilterList.Count);
var watcher4 = new FileSystemWatcher() { FilterList = null };
Assert.Equal(1, watcher4.FilterList.Count);
var watcher5 = new FileSystemWatcher() { FilterList = new Collection<string> { null } };
Assert.Equal("*", watcher5.Filter);
var watcher6 = new FileSystemWatcher();
watcher6.FilterList = new Collection<string> { "*.pdb", ".exe", ".doc" };
Assert.Equal(3, watcher6.FilterList.Count);
cc @danmosemsft @JeremyKuhne
What is the advantage of Collection<string> over List<string> here? It is just a simple wrapper for the latter.
@danmosemsft I am overriding InsertItem and SetItem to always convert "." to "*" while adding to FilterList which can`t be done with List
Ah...I missed that on my small screen.
@Anipik
Filter? Does it set the collection size to 1? Does it just set the first element?Filters to null or empty?Filters is null or empty? If we match everything, can/should we optimize?I will update the proposal soon
- Can you also describe what happens when you set Filter? Does it set the collection size to 1? Does it just set the first element?
It just sets the first element
- What happens if you set Filters to null or empty?
we can not set it null as it will be just ReadOnlyProperty. We can although empty the collection using clear() or RemoveAt. We can avoid that by overridding RemoveItem function in such a way that we never have empty collection.
5 a) What do we do if an element in Filters is null or empty? If we match everything, can/should we optimize?
We never have a null or empty element in the collection. We always replace it with * while adding to the collection
5 b) If we match everything, can/should we optimize?
We can optimise by not going further through the collection of the list if we encounter *.
- What about a constructor overload that takes the filters?
It will be breaking change as FileSystemWatcher("path", null) will no longer compile
I will add the usage code soon
Can you put the API in the namespace & class for context?
I meant:
C#
namespace System.IO
{
public class FileSystemWatcher
{
public Collection<string> FilterList { get; }
}
}
It will be breaking change as FileSystemWatcher("path", null) will no longer compile
Why not add one that takes IEnumerable<string>?
Please add the other details you've given above under "Implementation Details".
@JeremyKuhne Done and added some some examples too
We can discuss in review, but it seems least confusing to me for setting filter to be equivalent to setting a one item filter list, and for getting filter to throw if there is more than one entry in filterlist.
Looks a good. A few points:
List suffix, e.g. Filters.Filter will return the first item in Filters. If set, it will clear Filters and add the one item.
Most helpful comment
Video
Looks a good. A few points:
Listsuffix, e.g.Filters.Filterwill return the first item inFilters. If set, it will clearFiltersand add the one item.