aspnetcore/build/FileWatcher.shade

122 lines
4.2 KiB
Plaintext

use namespace="System.Collections.Concurrent"
functions
@{
public class FileWatcher
{
private readonly HashSet<string> _files = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly ConcurrentDictionary<string, HashSet<string>> _directories = new ConcurrentDictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
private readonly FileSystemWatcher _watcher;
public FileWatcher(string path)
{
_watcher = new FileSystemWatcher(path);
_watcher.IncludeSubdirectories = true;
_watcher.EnableRaisingEvents = true;
_watcher.Changed += OnWatcherChanged;
_watcher.Renamed += OnRenamed;
_watcher.Deleted += OnWatcherChanged;
_watcher.Created += OnWatcherChanged;
}
public event Action<string> OnChanged;
public void WatchDirectory(string path, string extension)
{
var extensions = _directories.GetOrAdd(path, _ => new HashSet<string>(StringComparer.OrdinalIgnoreCase));
extensions.Add(extension);
}
public bool WatchFile(string path)
{
return _files.Add(path);
}
public void Dispose()
{
_watcher.Dispose();
}
public bool ReportChange(string newPath, WatcherChangeTypes changeType)
{
return ReportChange(oldPath: null, newPath: newPath, changeType: changeType);
}
public bool ReportChange(string oldPath, string newPath, WatcherChangeTypes changeType)
{
if (HasChanged(oldPath, newPath, changeType))
{
if (oldPath != null)
{
Trace.TraceInformation("{0} -> {1}", oldPath, newPath);
}
else
{
Trace.TraceInformation("{0} -> {1}", changeType, newPath);
}
if (OnChanged != null)
{
OnChanged(newPath);
}
return true;
}
return false;
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
ReportChange(e.OldFullPath, e.FullPath, e.ChangeType);
}
private void OnWatcherChanged(object sender, FileSystemEventArgs e)
{
ReportChange(e.FullPath, e.ChangeType);
}
private bool HasChanged(string oldPath, string newPath, WatcherChangeTypes changeType)
{
// File changes
if (_files.Contains(newPath) ||
(oldPath != null && _files.Contains(oldPath)))
{
return true;
}
HashSet<string> extensions;
if (_directories.TryGetValue(newPath, out extensions) ||
_directories.TryGetValue(Path.GetDirectoryName(newPath), out extensions))
{
string extension = Path.GetExtension(newPath);
if (String.IsNullOrEmpty(extension))
{
// Assume it's a directory
if (changeType == WatcherChangeTypes.Created ||
changeType == WatcherChangeTypes.Renamed)
{
foreach (var e in extensions)
{
WatchDirectory(newPath, e);
}
}
else if(changeType == WatcherChangeTypes.Deleted)
{
return true;
}
// Ignore anything else
return false;
}
return extensions.Contains(extension);
}
return false;
}
}
}