Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/Zio/FileSystemExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ public static IEnumerable<FileSystemEntry> EnumerateFileSystemEntries(this IFile
}

/// <summary>
/// Gets a <see cref="FileSystemEntry"/> for the specified path. If the file or directory does no exist, throws a <see cref="FileNotFoundException"/>
/// Gets a <see cref="FileSystemEntry"/> for the specified path. If the file or directory does not exist, throws a <see cref="FileNotFoundException"/>
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="path">The file or directory path.</param>
Expand All @@ -740,7 +740,7 @@ public static FileSystemEntry GetFileSystemEntry(this IFileSystem fileSystem, UP
}

/// <summary>
/// Tries to get a <see cref="FileSystemEntry"/> for the specified path. If the file or directory does no exist, returns null.
/// Tries to get a <see cref="FileSystemEntry"/> for the specified path. If the file or directory does not exist, returns null.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="path">The file or directory path.</param>
Expand All @@ -762,7 +762,7 @@ public static FileSystemEntry TryGetFileSystemEntry(this IFileSystem fileSystem,
}

/// <summary>
/// Gets a <see cref="FileEntry"/> for the specified path. If the file does no exist, throws a <see cref="FileNotFoundException"/>
/// Gets a <see cref="FileEntry"/> for the specified path. If the file does not exist, throws a <see cref="FileNotFoundException"/>
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="filePath">The file path.</param>
Expand All @@ -777,7 +777,7 @@ public static FileEntry GetFileEntry(this IFileSystem fileSystem, UPath filePath
}

/// <summary>
/// Gets a <see cref="DirectoryEntry"/> for the specified path. If the file does no exist, throws a <see cref="DirectoryNotFoundException"/>
/// Gets a <see cref="DirectoryEntry"/> for the specified path. If the file does not exist, throws a <see cref="DirectoryNotFoundException"/>
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="directoryPath">The directory path.</param>
Expand All @@ -790,5 +790,21 @@ public static DirectoryEntry GetDirectoryEntry(this IFileSystem fileSystem, UPat
}
return new DirectoryEntry(fileSystem, directoryPath);
}

/// <summary>
/// Tries to watch the specified path. If watching the file system or path is not supported, returns null.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="path">The path to watch for changes.</param>
/// <returns>An <see cref="IFileSystemWatcher"/> instance or null if not supported.</returns>
public static IFileSystemWatcher TryWatch(this IFileSystem fileSystem, UPath path)
{
if (!fileSystem.CanWatch(path))
{
return null;
}

return fileSystem.Watch(path);
}
}
}
21 changes: 15 additions & 6 deletions src/Zio/FileSystems/AggregateFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ public void SetFileSystems(IEnumerable<IFileSystem> fileSystems)

foreach (var watcher in _watchers)
{
var newWatcher = fileSystem.Watch(watcher.Path);
watcher.Add(newWatcher);
if (fileSystem.CanWatch(watcher.Path))
{
var newWatcher = fileSystem.Watch(watcher.Path);
watcher.Add(newWatcher);
}
}
}
}
Expand All @@ -121,8 +124,11 @@ public virtual void AddFileSystem(IFileSystem fs)

foreach (var watcher in _watchers)
{
var newWatcher = fs.Watch(watcher.Path);
watcher.Add(newWatcher);
if (fs.CanWatch(watcher.Path))
{
var newWatcher = fs.Watch(watcher.Path);
watcher.Add(newWatcher);
}
}
}
else
Expand Down Expand Up @@ -372,14 +378,17 @@ protected override IFileSystemWatcher WatchImpl(UPath path)
{
var watcher = new AggregateFileSystemWatcher(this, path);

if (NextFileSystem != null)
if (NextFileSystem != null && NextFileSystem.CanWatch(path))
{
watcher.Add(NextFileSystem.Watch(path));
}

foreach (var fs in _fileSystems)
{
watcher.Add(fs.Watch(path));
if (fs.CanWatch(path))
{
watcher.Add(fs.Watch(path));
}
}

_watchers.Add(watcher);
Expand Down
33 changes: 30 additions & 3 deletions src/Zio/FileSystems/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,19 +438,46 @@ public IEnumerable<UPath> EnumeratePaths(UPath path, string searchPattern, Searc
// Watch API
// ----------------------------------------------

/// <inheritdoc />
public bool CanWatch(UPath path)
{
AssertNotDisposed();
return CanWatchImpl(ValidatePath(path));
}

/// <summary>
/// Implementation for <see cref="CanWatch"/>, <paramref name="path"/> is guaranteed to be absolute and validated through <see cref="ValidatePath"/>.
/// Checks if the file system and <paramref name="path"/> can be watched with <see cref="Watch"/>.
/// </summary>
/// <param name="path">The path to check.</param>
/// <returns>True if the the path can be watched on this file system.</returns>
protected virtual bool CanWatchImpl(UPath path)
{
return true;
}

/// <inheritdoc />
public IFileSystemWatcher Watch(UPath path)
{
AssertNotDisposed();
return WatchImpl(ValidatePath(path));

var validatedPath = ValidatePath(path);

if (!CanWatchImpl(validatedPath))
{
throw new NotSupportedException($"The file system or path `{validatedPath}` does not support watching");
}

return WatchImpl(validatedPath);
}

/// <summary>
/// Implementation for <see cref="Watch"/>, <paramref name="path"/> is guaranteed to be absolute and valudated through <see cref="ValidatePath"/>.
/// Returns an <see cref="IFileSystemWatcher"/> instance that can be used to watch for changes to files and directories in the given path.
/// Returns an <see cref="IFileSystemWatcher"/> instance that can be used to watch for changes to files and directories in the given path. The instance must be
/// configured before events are raised.
/// </summary>
/// <param name="path">The path to watch for changes.</param>
/// <returns>An <see cref="IFileSystemWatcher"/> instance that can be used to watch for changes.</returns>
/// <returns>An <see cref="IFileSystemWatcher"/> instance that watches the given path.</returns>
protected abstract IFileSystemWatcher WatchImpl(UPath path);

// ----------------------------------------------
Expand Down
18 changes: 12 additions & 6 deletions src/Zio/FileSystems/MountFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ public void Mount(UPath name, IFileSystem fileSystem)
continue;
}

var internalWatcher = fileSystem.Watch(remainingPath);
watcher.Add(new Watcher(this, name, remainingPath, internalWatcher));
if (fileSystem.CanWatch(remainingPath))
{
var internalWatcher = fileSystem.Watch(remainingPath);
watcher.Add(new Watcher(this, name, remainingPath, internalWatcher));
}
}
}
}
Expand Down Expand Up @@ -603,12 +606,15 @@ protected override IFileSystemWatcher WatchImpl(UPath path)
{
continue;
}

var internalWatcher = kvp.Value.Watch(remainingPath);
watcher.Add(new Watcher(this, kvp.Key, remainingPath, internalWatcher));

if (kvp.Value.CanWatch(remainingPath))
{
var internalWatcher = kvp.Value.Watch(remainingPath);
watcher.Add(new Watcher(this, kvp.Key, remainingPath, internalWatcher));
}
}

if (NextFileSystem != null)
if (NextFileSystem != null && NextFileSystem.CanWatch(path))
{
var internalWatcher = NextFileSystem.Watch(path);
watcher.Add(new Watcher(this, null, path, internalWatcher));
Expand Down
9 changes: 8 additions & 1 deletion src/Zio/IFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,16 @@ public interface IFileSystem : IDisposable
// Watch API
// ----------------------------------------------

/// <summary>
/// Checks if the file system and <paramref name="path"/> can be watched with <see cref="Watch"/>.
/// </summary>
/// <param name="path">The path to check.</param>
/// <returns>True if the the path can be watched on this file system.</returns>
bool CanWatch(UPath path);

/// <summary>
/// Returns an <see cref="IFileSystemWatcher"/> instance that can be used to watch for changes to files and directories in the given path. The instance must be
/// configured before events are called.
/// configured before events are raised.
/// </summary>
/// <param name="path">The path to watch for changes.</param>
/// <returns>An <see cref="IFileSystemWatcher"/> instance that watches the given path.</returns>
Expand Down