From fde2ba371032516bd3066bdf53c5135a232a70c8 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Fri, 8 Dec 2023 22:27:10 -0800 Subject: [PATCH] Improve Code Quality (#80) * Make TextSlice readonly * Update IFileSystem to use file-scoped namespaces * Make NodeResult readonly and pass by reference * Replace NET45 symbol with NETFRAMEWORK * Remove redundant scope * Eliminate a few allocations in ZipArchiveFileSystem and seal private classes * Improve nullability annotations --- src/Zio/FileSystemEntry.cs | 2 +- src/Zio/FileSystemExtensions.cs | 16 +- src/Zio/FileSystems/MemoryFileSystem.cs | 13 +- src/Zio/FileSystems/MountFileSystem.cs | 6 +- src/Zio/FileSystems/ZipArchiveFileSystem.cs | 52 ++- src/Zio/IFileSystem.cs | 453 ++++++++++---------- src/Zio/UPath.cs | 4 +- src/Zio/Zio.csproj | 4 +- 8 files changed, 270 insertions(+), 280 deletions(-) diff --git a/src/Zio/FileSystemEntry.cs b/src/Zio/FileSystemEntry.cs index aaf38b9..495f7d6 100644 --- a/src/Zio/FileSystemEntry.cs +++ b/src/Zio/FileSystemEntry.cs @@ -121,7 +121,7 @@ public override string ToString() } /// - public bool Equals(FileSystemEntry other) + public bool Equals(FileSystemEntry? other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; diff --git a/src/Zio/FileSystemExtensions.cs b/src/Zio/FileSystemExtensions.cs index 49594bd..c7882ca 100644 --- a/src/Zio/FileSystemExtensions.cs +++ b/src/Zio/FileSystemExtensions.cs @@ -340,12 +340,11 @@ public static byte[] ReadAllBytes(this IFileSystem fs, UPath path) public static string ReadAllText(this IFileSystem fs, UPath path) { var stream = fs.OpenFile(path, FileMode.Open, FileAccess.Read, FileShare.Read); + + using (var reader = new StreamReader(stream)) { - using (var reader = new StreamReader(stream)) - { - return reader.ReadToEnd(); - } - } + return reader.ReadToEnd(); + } } /// @@ -359,11 +358,10 @@ public static string ReadAllText(this IFileSystem fs, UPath path, Encoding encod { if (encoding is null) throw new ArgumentNullException(nameof(encoding)); var stream = fs.OpenFile(path, FileMode.Open, FileAccess.Read, FileShare.Read); + + using (var reader = new StreamReader(stream, encoding)) { - using (var reader = new StreamReader(stream, encoding)) - { - return reader.ReadToEnd(); - } + return reader.ReadToEnd(); } } diff --git a/src/Zio/FileSystems/MemoryFileSystem.cs b/src/Zio/FileSystems/MemoryFileSystem.cs index b4ec522..c96c2e8 100644 --- a/src/Zio/FileSystems/MemoryFileSystem.cs +++ b/src/Zio/FileSystems/MemoryFileSystem.cs @@ -796,7 +796,7 @@ protected override IEnumerable EnumeratePathsImpl(UPath path, string sear // and the time we are going to actually visit it, it might have been // removed in the meantime, so we make sure here that we have a folder // and we don't throw an error if it is not - if (!(result.Node is DirectoryNode)) + if (result.Node is not DirectoryNode) { continue; } @@ -885,7 +885,7 @@ protected override IEnumerable EnumerateItemsImpl(UPath path, Se // and the time we are going to actually visit it, it might have been // removed in the meantime, so we make sure here that we have a folder // and we don't throw an error if it is not - if (!(result.Node is DirectoryNode)) + if (result.Node is not DirectoryNode) { continue; } @@ -1106,8 +1106,7 @@ void AssertNoDestination(FileSystemNode node) } } - - private void ValidateDirectory([NotNull] FileSystemNode? node, UPath srcPath) + private static void ValidateDirectory([NotNull] FileSystemNode? node, UPath srcPath) { if (node is FileNode) { @@ -1120,7 +1119,7 @@ private void ValidateDirectory([NotNull] FileSystemNode? node, UPath srcPath) } } - private void ValidateFile([NotNull] FileSystemNode? node, UPath srcPath) + private static void ValidateFile([NotNull] FileSystemNode? node, UPath srcPath) { if (node is null) { @@ -1179,7 +1178,7 @@ private void CreateDirectoryNode(UPath path) ExitFindNode(EnterFindNode(path, FindNodeFlags.CreatePathIfNotExist | FindNodeFlags.NodeShared)); } - private struct NodeResult + private readonly struct NodeResult { public NodeResult(DirectoryNode? directory, FileSystemNode node, string? name, FindNodeFlags flags) { @@ -1214,7 +1213,7 @@ private enum FindNodeFlags KeepParentNodeShared = 1 << 6, } - private void ExitFindNode(NodeResult nodeResult) + private void ExitFindNode(in NodeResult nodeResult) { var flags = nodeResult.Flags; diff --git a/src/Zio/FileSystems/MountFileSystem.cs b/src/Zio/FileSystems/MountFileSystem.cs index 67924c0..2a666aa 100644 --- a/src/Zio/FileSystems/MountFileSystem.cs +++ b/src/Zio/FileSystems/MountFileSystem.cs @@ -33,7 +33,7 @@ public MountFileSystem(bool owned = true) : this(null, owned) /// Initializes a new instance of the class with a default backup filesystem. /// /// The default backup file system. - /// True if and mounted filesytems should be disposed when this instance is disposed. + /// True if and mounted filesystems should be disposed when this instance is disposed. public MountFileSystem(IFileSystem? defaultBackupFileSystem, bool owned = true) : base(defaultBackupFileSystem, owned) { _mounts = new SortedList(new UPathLengthComparer()); @@ -144,7 +144,7 @@ public IFileSystem Unmount(UPath name) { ValidateMountName(name); - IFileSystem mountFileSystem; + IFileSystem? mountFileSystem; if (!_mounts.TryGetValue(name, out mountFileSystem)) { @@ -1011,7 +1011,7 @@ private static UPath CombinePrefix(UPath prefix, UPath remaining) : prefix / remaining.ToRelative(); } - private void ValidateMountName(UPath name) + private static void ValidateMountName(UPath name) { name.AssertAbsolute(nameof(name)); if (name == UPath.Root) diff --git a/src/Zio/FileSystems/ZipArchiveFileSystem.cs b/src/Zio/FileSystems/ZipArchiveFileSystem.cs index 488848b..7c7ce23 100644 --- a/src/Zio/FileSystems/ZipArchiveFileSystem.cs +++ b/src/Zio/FileSystems/ZipArchiveFileSystem.cs @@ -33,7 +33,7 @@ public class ZipArchiveFileSystem : FileSystem private readonly Dictionary _openStreams; private readonly object _openStreamsLock = new(); -#if NET45 // .Net4.5 uses a backslash as directory separator +#if NETFRAMEWORK // .Net4.5 uses a backslash as directory separator private const char DirectorySeparator = '\\'; #else private const char DirectorySeparator = '/'; @@ -56,7 +56,7 @@ public ZipArchiveFileSystem(ZipArchive archive, bool isCaseSensitive = false, Co { throw new ArgumentNullException(nameof(archive)); } -#if NET45 // .Net4.5 uses a backslash as directory separator +#if NETFRAMEWORK // .Net4.5 uses a backslash as directory separator foreach (var entry in _archive.Entries) { entry.FullName.Replace('/', DirectorySeparator); @@ -112,7 +112,7 @@ public ZipArchiveFileSystem(ZipArchiveMode mode = ZipArchiveMode.Update, bool le private ZipArchiveEntry? GetEntry(string path) { -#if NET45 +#if NETFRAMEWORK path = path.Replace('/', DirectorySeparator); #else path = path.Replace('\\', DirectorySeparator); @@ -243,7 +243,7 @@ protected override void CreateDirectoryImpl(UPath path) } var entryPath = RemoveLeadingSlash(path); -#if NET45 +#if NETFRAMEWORK entryPath = entryPath.Replace('/', DirectorySeparator); #else entryPath = entryPath.Replace('\\', DirectorySeparator); @@ -256,7 +256,7 @@ protected override void CreateDirectoryImpl(UPath path) protected override void DeleteDirectoryImpl(UPath path, bool isRecursive) { var entryPath = RemoveLeadingSlash(ConvertPathToDirectory(path)); -#if NET45 +#if NETFRAMEWORK entryPath = entryPath.Replace('/', DirectorySeparator); #else entryPath = entryPath.Replace('\\', DirectorySeparator); @@ -427,7 +427,7 @@ private IEnumerable EnumeratePathsStr(UPath path, string searchPattern, var search = SearchPattern.Parse(ref path, ref searchPattern); var entryPath = RemoveLeadingSlash(path); var root = ConvertPathToDirectory(entryPath); -#if NET45 +#if NETFRAMEWORK root = root.Replace('/', '\\'); #else root = root.Replace('\\', '/'); @@ -484,7 +484,7 @@ protected override bool FileExistsImpl(UPath path) protected override FileAttributes GetAttributesImpl(UPath path) { var entry = GetEntry(path.FullName) ?? GetEntry(ConvertPathToDirectory(path)); - if (entry == null) + if (entry is null) { throw FileSystemExceptionHelper.NewFileNotFoundException(path); } @@ -562,7 +562,7 @@ protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath) var srcDir = RemoveLeadingSlash(ConvertPathToDirectory(srcPath.FullName)); var destDir = RemoveLeadingSlash(ConvertPathToDirectory(destPath.FullName)); -#if NET45 +#if NETFRAMEWORK srcDir = srcDir.Replace('/', DirectorySeparator); destDir = destDir.Replace('/', DirectorySeparator); #else @@ -570,7 +570,7 @@ protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath) destDir = destDir.Replace('\\', DirectorySeparator); #endif _entriesLock.EnterReadLock(); - var entries = new ZipArchiveEntry[0]; + var entries = Array.Empty(); try { entries = _archive.Entries.Where(e => e.FullName.StartsWith(srcDir, _isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)).ToArray(); @@ -618,12 +618,8 @@ protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath) /// protected override void MoveFileImpl(UPath srcPath, UPath destPath) { - var srcEntry = GetEntry(srcPath.FullName); - if (srcEntry == null) - { - throw FileSystemExceptionHelper.NewFileNotFoundException(srcPath); - } - + var srcEntry = GetEntry(srcPath.FullName) ?? throw FileSystemExceptionHelper.NewFileNotFoundException(srcPath); + if (!DirectoryExistsImpl(destPath.GetDirectory())) { throw FileSystemExceptionHelper.NewDirectoryNotFoundException(destPath.GetDirectory()); @@ -633,8 +629,7 @@ protected override void MoveFileImpl(UPath srcPath, UPath destPath) if (destEntry != null) { throw new IOException("Cannot overwrite existing file."); - } - + } destEntry = CreateEntry(destPath.FullName); TryGetDispatcher()?.RaiseCreated(destPath); @@ -730,7 +725,7 @@ protected override Stream OpenFileImpl(UPath path, FileMode mode, FileAccess acc protected override void ReplaceFileImpl(UPath srcPath, UPath destPath, UPath destBackupPath, bool ignoreMetadataErrors) { var sourceEntry = GetEntry(srcPath.FullName); - if (sourceEntry == null) + if (sourceEntry is null) { throw FileSystemExceptionHelper.NewFileNotFoundException(srcPath); } @@ -813,7 +808,7 @@ protected override void SetLastAccessTimeImpl(UPath path, DateTime time) protected override void SetLastWriteTimeImpl(UPath path, DateTime time) { var entry = GetEntry(path.FullName) ?? GetEntry(ConvertPathToDirectory(path.FullName)); - if (entry == null) + if (entry is null) { throw FileSystemExceptionHelper.NewFileNotFoundException(path); } @@ -856,7 +851,7 @@ private void RemoveEntry(ZipArchiveEntry entry) private ZipArchiveEntry CreateEntry(string path) { path = RemoveLeadingSlash(path); -#if NET45 +#if NETFRAMEWORK path = path.Replace('/', DirectorySeparator); #else path = path.Replace('\\', DirectorySeparator); @@ -879,17 +874,19 @@ private ZipArchiveEntry CreateEntry(string path) } } - private string GetName(ZipArchiveEntry entry) + private static readonly char[] s_slashChars = { '/', '\\' }; + + private static string GetName(ZipArchiveEntry entry) { - var name = entry.FullName.TrimEnd('/', '\\'); - var index = name.LastIndexOfAny(new[] { '/', '\\' }); + var name = entry.FullName.TrimEnd(s_slashChars); + var index = name.LastIndexOfAny(s_slashChars); return name.Substring(index + 1); } private static string GetParent(string path) { - path = path.TrimEnd('/', '\\'); - var lastIndex = path.LastIndexOfAny(new[] { '/', '\\' }); + path = path.TrimEnd(s_slashChars); + var lastIndex = path.LastIndexOfAny(s_slashChars); return lastIndex == -1 ? "" : path.Substring(0, lastIndex); } @@ -926,8 +923,7 @@ private static string RemoveLeadingSlash(string path) } } - - private class ZipEntryStream : Stream + private sealed class ZipEntryStream : Stream { private readonly ZipArchiveEntry _entry; private readonly ZipArchiveFileSystem _fileSystem; @@ -1029,7 +1025,7 @@ public override void Close() } } - private class EntryState + private sealed class EntryState { public EntryState(FileShare share) { diff --git a/src/Zio/IFileSystem.cs b/src/Zio/IFileSystem.cs index ba46d54..7de7037 100644 --- a/src/Zio/IFileSystem.cs +++ b/src/Zio/IFileSystem.cs @@ -2,235 +2,232 @@ // This file is licensed under the BSD-Clause 2 license. // See the license.txt file in the project root for more information. -using System; -using System.Collections.Generic; using System.IO; -namespace Zio +namespace Zio; + +/// +/// Interface of a FileSystem. +/// +public interface IFileSystem : IDisposable { + // ---------------------------------------------- + // Directory API + // ---------------------------------------------- + + /// + /// Creates all directories and subdirectories in the specified path unless they already exist. + /// + /// The directory to create. + void CreateDirectory(UPath path); + + /// + /// Determines whether the given path refers to an existing directory on disk. + /// + /// The path to test. + /// true if the given path refers to an existing directory on disk, false otherwise. + bool DirectoryExists(UPath path); + + /// + /// Moves a directory and its contents to a new location. + /// + /// The path of the directory to move. + /// The path to the new location for + void MoveDirectory(UPath srcPath, UPath destPath); + + /// + /// Deletes the specified directory and, if indicated, any subdirectories and files in the directory. + /// + /// The path of the directory to remove. + /// true to remove directories, subdirectories, and files in path; otherwise, false. + void DeleteDirectory(UPath path, bool isRecursive); + + // ---------------------------------------------- + // File API + // ---------------------------------------------- + + /// + /// Copies an existing file to a new file. Overwriting a file of the same name is allowed. + /// + /// The path of the file to copy. + /// The path of the destination file. This cannot be a directory. + /// true if the destination file can be overwritten; otherwise, false. + void CopyFile(UPath srcPath, UPath destPath, bool overwrite); + + /// + /// Replaces the contents of a specified file with the contents of another file, deleting the original file, and creating a backup of the replaced file and optionally ignores merge errors. + /// + /// The path of a file that replaces the file specified by . + /// The path of the file being replaced. + /// The path of the backup file (maybe null, in that case, it doesn't create any backup) + /// true to ignore merge errors (such as attributes and access control lists (ACLs)) from the replaced file to the replacement file; otherwise, false. + void ReplaceFile(UPath srcPath, UPath destPath, UPath destBackupPath, bool ignoreMetadataErrors); + + /// + /// Gets the size, in bytes, of a file. + /// + /// The path of a file. + /// The size, in bytes, of the file + long GetFileLength(UPath path); + + /// + /// Determines whether the specified file exists. + /// + /// The path. + /// true if the caller has the required permissions and path contains the name of an existing file; + /// otherwise, false. This method also returns false if path is null, an invalid path, or a zero-length string. + /// If the caller does not have sufficient permissions to read the specified file, + /// no exception is thrown and the method returns false regardless of the existence of path. + bool FileExists(UPath path); + + /// + /// Moves a specified file to a new location, providing the option to specify a new file name. + /// + /// The path of the file to move. + /// The new path and name for the file. + void MoveFile(UPath srcPath, UPath destPath); + + /// + /// Deletes the specified file. + /// + /// The path of the file to be deleted. + void DeleteFile(UPath path); + + /// + /// Opens a file on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + /// + /// The path to the file to open. + /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A value that specifies the operations that can be performed on the file. + /// A value specifying the type of access other threads have to the file. + /// A file on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. + Stream OpenFile(UPath path, FileMode mode, FileAccess access, FileShare share = FileShare.None); + + // ---------------------------------------------- + // Metadata API + // ---------------------------------------------- + + /// + /// Gets the of the file or directory on the path. + /// + /// The path to the file or directory. + /// The of the file or directory on the path. + FileAttributes GetAttributes(UPath path); + /// - /// Interface of a FileSystem. - /// - public interface IFileSystem : IDisposable - { - // ---------------------------------------------- - // Directory API - // ---------------------------------------------- - - /// - /// Creates all directories and subdirectories in the specified path unless they already exist. - /// - /// The directory to create. - void CreateDirectory(UPath path); - - /// - /// Determines whether the given path refers to an existing directory on disk. - /// - /// The path to test. - /// true if the given path refers to an existing directory on disk, false otherwise. - bool DirectoryExists(UPath path); - - /// - /// Moves a directory and its contents to a new location. - /// - /// The path of the directory to move. - /// The path to the new location for - void MoveDirectory(UPath srcPath, UPath destPath); - - /// - /// Deletes the specified directory and, if indicated, any subdirectories and files in the directory. - /// - /// The path of the directory to remove. - /// true to remove directories, subdirectories, and files in path; otherwise, false. - void DeleteDirectory(UPath path, bool isRecursive); - - // ---------------------------------------------- - // File API - // ---------------------------------------------- - - /// - /// Copies an existing file to a new file. Overwriting a file of the same name is allowed. - /// - /// The path of the file to copy. - /// The path of the destination file. This cannot be a directory. - /// true if the destination file can be overwritten; otherwise, false. - void CopyFile(UPath srcPath, UPath destPath, bool overwrite); - - /// - /// Replaces the contents of a specified file with the contents of another file, deleting the original file, and creating a backup of the replaced file and optionally ignores merge errors. - /// - /// The path of a file that replaces the file specified by . - /// The path of the file being replaced. - /// The path of the backup file (maybe null, in that case, it doesn't create any backup) - /// true to ignore merge errors (such as attributes and access control lists (ACLs)) from the replaced file to the replacement file; otherwise, false. - void ReplaceFile(UPath srcPath, UPath destPath, UPath destBackupPath, bool ignoreMetadataErrors); - - /// - /// Gets the size, in bytes, of a file. - /// - /// The path of a file. - /// The size, in bytes, of the file - long GetFileLength(UPath path); - - /// - /// Determines whether the specified file exists. - /// - /// The path. - /// true if the caller has the required permissions and path contains the name of an existing file; - /// otherwise, false. This method also returns false if path is null, an invalid path, or a zero-length string. - /// If the caller does not have sufficient permissions to read the specified file, - /// no exception is thrown and the method returns false regardless of the existence of path. - bool FileExists(UPath path); - - /// - /// Moves a specified file to a new location, providing the option to specify a new file name. - /// - /// The path of the file to move. - /// The new path and name for the file. - void MoveFile(UPath srcPath, UPath destPath); - - /// - /// Deletes the specified file. - /// - /// The path of the file to be deleted. - void DeleteFile(UPath path); - - /// - /// Opens a file on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. - /// - /// The path to the file to open. - /// A value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. - /// A value that specifies the operations that can be performed on the file. - /// A value specifying the type of access other threads have to the file. - /// A file on the specified path, having the specified mode with read, write, or read/write access and the specified sharing option. - Stream OpenFile(UPath path, FileMode mode, FileAccess access, FileShare share = FileShare.None); - - // ---------------------------------------------- - // Metadata API - // ---------------------------------------------- - - /// - /// Gets the of the file or directory on the path. - /// - /// The path to the file or directory. - /// The of the file or directory on the path. - FileAttributes GetAttributes(UPath path); - - /// - /// Sets the specified of the file or directory on the specified path. - /// - /// The path to the file or directory. - /// A bitwise combination of the enumeration values. - void SetAttributes(UPath path, FileAttributes attributes); - - /// - /// Returns the creation date and time of the specified file or directory. - /// - /// The path to a file or directory for which to obtain creation date and time information. - /// A structure set to the creation date and time for the specified file or directory. This value is expressed in local time. - DateTime GetCreationTime(UPath path); - - /// - /// Sets the date and time the file was created. - /// - /// The path to a file or directory for which to set the creation date and time. - /// A containing the value to set for the creation date and time of path. This value is expressed in local time. - void SetCreationTime(UPath path, DateTime time); - - /// - /// Returns the last access date and time of the specified file or directory. - /// - /// The path to a file or directory for which to obtain creation date and time information. - /// A structure set to the last access date and time for the specified file or directory. This value is expressed in local time. - DateTime GetLastAccessTime(UPath path); - - /// - /// Sets the date and time the file was last accessed. - /// - /// The path to a file or directory for which to set the last access date and time. - /// A containing the value to set for the last access date and time of path. This value is expressed in local time. - void SetLastAccessTime(UPath path, DateTime time); - - /// - /// Returns the last write date and time of the specified file or directory. - /// - /// The path to a file or directory for which to obtain creation date and time information. - /// A structure set to the last write date and time for the specified file or directory. This value is expressed in local time. - DateTime GetLastWriteTime(UPath path); - - /// - /// Sets the date and time that the specified file was last written to. - /// - /// The path to a file or directory for which to set the last write date and time. - /// A containing the value to set for the last write date and time of path. This value is expressed in local time. - void SetLastWriteTime(UPath path, DateTime time); - - // ---------------------------------------------- - // Search API - // ---------------------------------------------- - - /// - /// Returns an enumerable collection of file names and/or directory names that match a search pattern in a specified path, and optionally searches subdirectories. - /// - /// The path to the directory to search. - /// The search string to match against file-system entries in path. This parameter can contain a combination of valid literal path and wildcard (* and ?) characters (see Remarks), but doesn't support regular expressions. - /// One of the enumeration values that specifies whether the search operation should include only the current directory or should include all subdirectories. - /// The search target either or only or . - /// An enumerable collection of file-system paths in the directory specified by path and that match the specified search pattern, option and target. - IEnumerable EnumeratePaths(UPath path, string searchPattern, SearchOption searchOption, SearchTarget searchTarget); - - /// - /// Returns an enumerable collection of that match a search pattern in a specified path, and optionally searches subdirectories. - /// - /// The path to the directory to search. - /// The search string to match against file-system entries in path. This parameter can contain a combination of valid literal path and wildcard (* and ?) characters (see Remarks), but doesn't support regular expressions. - /// One of the enumeration values that specifies whether the search operation should include only the current directory or should include all subdirectories. - /// An enumerable collection of in the directory specified by path and that match the specified search pattern, option and target. - IEnumerable EnumerateItems(UPath path, SearchOption searchOption, SearchPredicate? searchPredicate = null); - - // ---------------------------------------------- - // Watch API - // ---------------------------------------------- - - /// - /// Checks if the file system and can be watched with . - /// - /// The path to check. - /// True if the the path can be watched on this file system. - bool CanWatch(UPath path); - - /// - /// Returns an 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. - /// - /// The path to watch for changes. - /// An instance that watches the given path. - IFileSystemWatcher Watch(UPath path); - - // ---------------------------------------------- - // Path API - // ---------------------------------------------- - - /// - /// Converts the specified path to the underlying path used by this . In case of a , it - /// would represent the actual path on the disk. - /// - /// The path. - /// The converted system path according to the specified path. - string ConvertPathToInternal(UPath path); - - /// - /// Converts the specified system path to a path. - /// - /// The system path. - /// The converted path according to the system path. - UPath ConvertPathFromInternal(string systemPath); - } - - /// - /// Used by . - /// - /// The file system item to filer. - /// true if the item should be kept; otherwise false. - public delegate bool SearchPredicate(ref FileSystemItem item); -} \ No newline at end of file + /// Sets the specified of the file or directory on the specified path. + /// + /// The path to the file or directory. + /// A bitwise combination of the enumeration values. + void SetAttributes(UPath path, FileAttributes attributes); + + /// + /// Returns the creation date and time of the specified file or directory. + /// + /// The path to a file or directory for which to obtain creation date and time information. + /// A structure set to the creation date and time for the specified file or directory. This value is expressed in local time. + DateTime GetCreationTime(UPath path); + + /// + /// Sets the date and time the file was created. + /// + /// The path to a file or directory for which to set the creation date and time. + /// A containing the value to set for the creation date and time of path. This value is expressed in local time. + void SetCreationTime(UPath path, DateTime time); + + /// + /// Returns the last access date and time of the specified file or directory. + /// + /// The path to a file or directory for which to obtain creation date and time information. + /// A structure set to the last access date and time for the specified file or directory. This value is expressed in local time. + DateTime GetLastAccessTime(UPath path); + + /// + /// Sets the date and time the file was last accessed. + /// + /// The path to a file or directory for which to set the last access date and time. + /// A containing the value to set for the last access date and time of path. This value is expressed in local time. + void SetLastAccessTime(UPath path, DateTime time); + + /// + /// Returns the last write date and time of the specified file or directory. + /// + /// The path to a file or directory for which to obtain creation date and time information. + /// A structure set to the last write date and time for the specified file or directory. This value is expressed in local time. + DateTime GetLastWriteTime(UPath path); + + /// + /// Sets the date and time that the specified file was last written to. + /// + /// The path to a file or directory for which to set the last write date and time. + /// A containing the value to set for the last write date and time of path. This value is expressed in local time. + void SetLastWriteTime(UPath path, DateTime time); + + // ---------------------------------------------- + // Search API + // ---------------------------------------------- + + /// + /// Returns an enumerable collection of file names and/or directory names that match a search pattern in a specified path, and optionally searches subdirectories. + /// + /// The path to the directory to search. + /// The search string to match against file-system entries in path. This parameter can contain a combination of valid literal path and wildcard (* and ?) characters (see Remarks), but doesn't support regular expressions. + /// One of the enumeration values that specifies whether the search operation should include only the current directory or should include all subdirectories. + /// The search target either or only or . + /// An enumerable collection of file-system paths in the directory specified by path and that match the specified search pattern, option and target. + IEnumerable EnumeratePaths(UPath path, string searchPattern, SearchOption searchOption, SearchTarget searchTarget); + + /// + /// Returns an enumerable collection of that match a search pattern in a specified path, and optionally searches subdirectories. + /// + /// The path to the directory to search. + /// The search string to match against file-system entries in path. This parameter can contain a combination of valid literal path and wildcard (* and ?) characters (see Remarks), but doesn't support regular expressions. + /// One of the enumeration values that specifies whether the search operation should include only the current directory or should include all subdirectories. + /// An enumerable collection of in the directory specified by path and that match the specified search pattern, option and target. + IEnumerable EnumerateItems(UPath path, SearchOption searchOption, SearchPredicate? searchPredicate = null); + + // ---------------------------------------------- + // Watch API + // ---------------------------------------------- + + /// + /// Checks if the file system and can be watched with . + /// + /// The path to check. + /// True if the the path can be watched on this file system. + bool CanWatch(UPath path); + + /// + /// Returns an 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. + /// + /// The path to watch for changes. + /// An instance that watches the given path. + IFileSystemWatcher Watch(UPath path); + + // ---------------------------------------------- + // Path API + // ---------------------------------------------- + + /// + /// Converts the specified path to the underlying path used by this . In case of a , it + /// would represent the actual path on the disk. + /// + /// The path. + /// The converted system path according to the specified path. + string ConvertPathToInternal(UPath path); + + /// + /// Converts the specified system path to a path. + /// + /// The system path. + /// The converted path according to the system path. + UPath ConvertPathFromInternal(string systemPath); +} + +/// +/// Used by . +/// +/// The file system item to filer. +/// true if the item should be kept; otherwise false. +public delegate bool SearchPredicate(ref FileSystemItem item); \ No newline at end of file diff --git a/src/Zio/UPath.cs b/src/Zio/UPath.cs index f5f98cb..f80d9a5 100644 --- a/src/Zio/UPath.cs +++ b/src/Zio/UPath.cs @@ -194,7 +194,7 @@ public bool Equals(UPath other) } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is UPath path && Equals(path); } @@ -452,7 +452,7 @@ public InternalHelper() } } - private struct TextSlice + private readonly struct TextSlice { public TextSlice(int start, int end) { diff --git a/src/Zio/Zio.csproj b/src/Zio/Zio.csproj index a2c7037..19eb26c 100644 --- a/src/Zio/Zio.csproj +++ b/src/Zio/Zio.csproj @@ -13,7 +13,7 @@ readme.md https://github.com/xoofx/zio BSD-2-Clause - 10 + 11 true true @@ -72,7 +72,7 @@ - $(AdditionalConstants);NET45;HAS_ZIPARCHIVE + $(AdditionalConstants);HAS_ZIPARCHIVE