public void TestExtensions() { { var path = new UPath("/a/b/c/d.txt"); Assert.Equal(new UPath("/a/b/c"), path.GetDirectory()); Assert.Equal("d.txt", path.GetName()); Assert.Equal("d", path.GetNameWithoutExtension()); Assert.Equal(".txt", path.GetExtensionWithDot()); var newPath = path.ChangeExtension(".zip"); Assert.Equal("/a/b/c/d.zip", newPath.FullName); Assert.Equal(new UPath("a/b/c/d.txt"), path.ToRelative()); Assert.Equal(path, path.AssertAbsolute()); Assert.Throws <ArgumentNullException>(() => new UPath().AssertNotNull()); Assert.Throws <ArgumentException>(() => new UPath("not_absolute").AssertAbsolute()); } { var path = new UPath("d.txt"); Assert.Equal(UPath.Empty, path.GetDirectory()); Assert.Equal("d.txt", path.GetName()); Assert.Equal("d", path.GetNameWithoutExtension()); Assert.Equal(".txt", path.GetExtensionWithDot()); var newPath = path.ChangeExtension(".zip"); Assert.Equal("d.zip", newPath.FullName); Assert.Equal(new UPath("d.txt"), path.ToRelative()); } }
public FileOpenedEventArgs(UPath fullPath) { fullPath.AssertNotNull(nameof(fullPath)); fullPath.AssertAbsolute(nameof(fullPath)); OpenedPath = fullPath; }
/// <summary> /// Finds the list of <see cref="FileSystemEntry"/> for each file or directory found at the specified path for each registered filesystems (in order). /// The type of the first entry (file or directory) dictates the type of the following entries in the list (e.g if a file is coming first, only files will be showned for the specified path). /// </summary> /// <param name="path">To check for an entry</param> /// <returns>A list of file entries for the specified path</returns> public List <FileSystemEntry> FindFileSystemEntries(UPath path) { path.AssertAbsolute(); var paths = new List <FileSystemPath>(); FindPaths(path, SearchTarget.Both, paths); var result = new List <FileSystemEntry>(paths.Count); if (paths.Count == 0) { return(result); } var isFile = paths[0].IsFile; foreach (var pathItem in paths) { if (pathItem.IsFile == isFile) { if (isFile) { result.Add(new FileEntry(pathItem.FileSystem, pathItem.Path)); } else { result.Add(new DirectoryEntry(pathItem.FileSystem, pathItem.Path)); } } } return(result); }
public bool TryCopyFile(FileEntry fromFile, UPath outputPath) { if (fromFile == null) { throw new ArgumentNullException(nameof(fromFile)); } outputPath.AssertAbsolute(nameof(outputPath)); var outputFile = new FileEntry(Site.OutputFileSystem, outputPath); TrackDestination(outputFile, fromFile); if (!outputFile.Exists || (fromFile.LastWriteTime > outputFile.LastWriteTime)) { CreateDirectory(outputFile.Directory); if (Site.CanTrace()) { Site.Trace($"Copy file from [{fromFile} to [{outputPath}]"); } fromFile.CopyTo(outputFile.FullName, true); return(true); // Update statistics //stat.Static = true; //stat.OutputBytes += fromFile.Length; } return(false); }
private void AssertMountName(UPath name) { name.AssertAbsolute(nameof(name)); if (name == UPath.Root) { throw new ArgumentException("The mount name cannot be a `/` root filesystem", nameof(name)); } }
/// <summary> /// Initializes a new instance of the <see cref="SubFileSystem"/> class. /// </summary> /// <param name="fileSystem">The file system to create a view from.</param> /// <param name="subPath">The sub path view to create filesystem.</param> /// <param name="owned">True if <paramref name="fileSystem"/> should be disposed when this instance is disposed.</param> /// <exception cref="DirectoryNotFoundException">If the directory subPath does not exist in the delegate FileSystem</exception> public SubFileSystem(IFileSystem fileSystem, UPath subPath, bool owned = true) : base(fileSystem, owned) { SubPath = subPath.AssertAbsolute(nameof(subPath)); if (!fileSystem.DirectoryExists(SubPath)) { throw NewDirectoryNotFoundException(SubPath); } }
public FileRenamedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath, UPath oldFullPath) : base(fileSystem, changeType, fullPath) { fullPath.AssertNotNull(nameof(oldFullPath)); fullPath.AssertAbsolute(nameof(oldFullPath)); OldFullPath = oldFullPath; OldName = oldFullPath.GetName(); }
/// <summary> /// Validates the specified path (Check that it is absolute by default) /// </summary> /// <param name="path">The path.</param> /// <param name="name">The name.</param> /// <param name="allowNull">if set to <c>true</c> the path is allowed to be null. <c>false</c> otherwise.</param> /// <returns>The path validated</returns> protected UPath ValidatePath(UPath path, string name = "path", bool allowNull = false) { if (allowNull && path.IsNull) { return(path); } path.AssertAbsolute(name); return(ValidatePathImpl(path, name)); }
public FileSystemWatcher(IFileSystem fileSystem, UPath path) { if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } path.AssertAbsolute(); FileSystem = fileSystem; Path = path; }
private void AssertMountName(UPath name) { name.AssertAbsolute(); if (name == UPath.Root) { throw new ArgumentException("The mount name cannot be a `/` root filesystem", nameof(name)); } if (name.GetDirectory() != UPath.Root) { throw new ArgumentException("The mount name cannot contain subpath and must contain only a root path e.g `/mount`", nameof(name)); } }
/// <summary> /// Finds the first <see cref="FileSystemEntry"/> from this aggregate system found at the specified path for each registered filesystems (in order). /// The type of the first entry (file or directory) dictates the type of the following entries in the list (e.g if a file is coming first, only files will be showned for the specified path). /// </summary> /// <param name="path">To check for an entry</param> /// <returns>A file system entry or null if it was not found.</returns> public FileSystemEntry?FindFirstFileSystemEntry(UPath path) { path.AssertAbsolute(); var entry = TryGetPath(path); if (!entry.HasValue) { return(null); } var pathItem = entry.Value; return(pathItem.IsFile ? (FileSystemEntry) new FileEntry(pathItem.FileSystem, pathItem.Path) : new DirectoryEntry(pathItem.FileSystem, pathItem.Path)); }
public FileChangedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath) { if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } fullPath.AssertNotNull(nameof(fullPath)); fullPath.AssertAbsolute(nameof(fullPath)); FileSystem = fileSystem; ChangeType = changeType; FullPath = fullPath; Name = fullPath.GetName(); }
/// <summary> /// Attempts to find information about the mount that a given path maps to. /// </summary> /// <param name="path">The path to search for.</param> /// <param name="name">The mount name that the <paramref name="path"/> belongs to.</param> /// <param name="fileSystem">The mounted filesystem that the <paramref name="path"/> is located in.</param> /// <param name="fileSystemPath">The path inside of <paramref name="fileSystem"/> that refers to the file at <paramref name="path"/>.</param> /// <returns>True if the <paramref name="path"/> was found in a mounted filesystem.</returns> /// <exception cref="System.ArgumentNullException">The <paramref name="path"/> must not be null.</exception> /// <exception cref="System.ArgumentException">The <paramref name="path"/> must be absolute.</exception> public bool TryGetMount(UPath path, out UPath name, out IFileSystem fileSystem, out UPath fileSystemPath) { path.AssertNotNull(); path.AssertAbsolute(); var fs = TryGetMountOrNext(ref path, out name); if (fs == null || name.IsNull) { name = null; fileSystem = null; fileSystemPath = null; return(false); } fileSystem = fs; fileSystemPath = path; return(true); }
private SearchPattern(ref UPath path, ref string searchPattern) { path.AssertAbsolute(); if (searchPattern == null) { throw new ArgumentNullException(nameof(searchPattern)); } _exactMatch = null; _regexMatch = null; //Optimized path, most common case if (searchPattern == "*" && path == UPath.Root) { return; } if (searchPattern.StartsWith("/")) { throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`"); } searchPattern = searchPattern.Replace('\\', '/'); // If the path contains any directory, we need to concatenate the directory part with the input path if (searchPattern.IndexOf('/') > 0) { var pathPattern = new UPath(searchPattern); var directory = pathPattern.GetDirectory(); if (!directory.IsNull && !directory.IsEmpty) { path /= directory; } searchPattern = pathPattern.GetName(); // If the search pattern is again a plain any, optimized path if (searchPattern == "*") { return; } } var startIndex = 0; StringBuilder builder = null; try { int nextIndex; while ((nextIndex = searchPattern.IndexOfAny(SpecialChars, startIndex)) >= 0) { if (builder == null) { builder = new StringBuilder(); builder.Append("^"); } var lengthToEscape = nextIndex - startIndex; if (lengthToEscape > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, lengthToEscape)); builder.Append(toEscape); } var c = searchPattern[nextIndex]; var regexPatternPart = c == '*' ? ".*" : "."; builder.Append(regexPatternPart); startIndex = nextIndex + 1; } if (builder == null) { _exactMatch = searchPattern; } else { var length = searchPattern.Length - startIndex; if (length > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, length)); builder.Append(toEscape); } builder.Append("$"); var regexPattern = builder.ToString(); _regexMatch = new Regex(regexPattern); } } finally { if (builder != null) { builder.Length = 0; } } }
private SearchPattern(ref UPath path, ref string searchPattern) { path.AssertAbsolute(); if (searchPattern == null) { throw new ArgumentNullException(nameof(searchPattern)); } _exactMatch = null; _regexMatch = null; //Optimized path, most common case if (searchPattern == "*" && path == UPath.Root) { return; } if (searchPattern.StartsWith("/")) { throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`"); } // Normalize path separators searchPattern = searchPattern.Replace('\\', '/'); // If the path contains any directory, we need to concatenate the directory part with the input path (?) if (searchPattern.IndexOf('/') > 0) { var pathPattern = new UPath(searchPattern); var directory = pathPattern.GetDirectory(); if (!directory.IsNull && !directory.IsEmpty) { path /= directory; } searchPattern = pathPattern.GetName(); // If the search pattern is again a plain any, optimized path if (searchPattern == "*") { return; } } var regexBuilder = new StringBuilder("^"); bool containsWildcards = false; // Loop through parts of searchPattern separated by wildcards for (int index = 0, nextWildcard = 0; nextWildcard != -1; index = nextWildcard + 1) { // Next wildcard occurence nextWildcard = searchPattern.IndexOfAny(WildcardChars, index); // Escape & append text up to next wildcard // If no new wildcard, append up to end of string var endOfPart = nextWildcard != -1 ? nextWildcard : searchPattern.Length; regexBuilder.Append(Regex.Escape(searchPattern.Substring(index, endOfPart - index))); // Convert & append wildcard, if applicable if (nextWildcard != -1) { var wc = searchPattern[nextWildcard]; var regexPatternPart = wc switch { '*' => ".*", '?' => ".", _ => throw new ArgumentException($"Unknown wildcard: {wc}") }; regexBuilder.Append(regexPatternPart); containsWildcards = true; } } regexBuilder.Append("$"); if (!containsWildcards) { _exactMatch = searchPattern; } else { _regexMatch = new Regex(regexBuilder.ToString()); } } }
public bool TryCopyContentToOutput(ContentObject fromFile, UPath outputPath) { if (fromFile == null) { throw new ArgumentNullException(nameof(fromFile)); } outputPath.AssertAbsolute(); var clock = Stopwatch.StartNew(); var outputFile = new FileEntry(Site.OutputFileSystem, outputPath); var outputDir = outputFile.Directory; if (outputDir == null) { throw new ArgumentException("Output directory cannot be empty", nameof(outputPath)); } TrackDestination(outputFile, fromFile.SourceFile); var stat = Site.Statistics.GetContentStat(fromFile); CreateDirectory(outputDir); try { // If the file has a content, we will use this instead if (fromFile.Content != null) { if (Site.CanTrace()) { Site.Trace($"Write file [{outputFile}]"); } using (var writer = new StreamWriter(outputFile.Open(FileMode.Create, FileAccess.Write))) { writer.Write(fromFile.Content); writer.Flush(); // Update statistics stat.Static = false; stat.OutputBytes += writer.BaseStream.Length; } } // If the source file is not newer than the destination file, don't overwrite it else if (fromFile.SourceFile != null && (!outputFile.Exists || (fromFile.ModifiedTime > outputFile.LastWriteTime))) { if (Site.CanTrace()) { Site.Trace($"Write file [{outputFile}]"); } // If the output file is readonly, make sure that it is not readonly before overwriting if (outputFile.Exists && (outputFile.Attributes & FileAttributes.ReadOnly) != 0) { outputFile.Attributes = outputFile.Attributes & ~FileAttributes.ReadOnly; } fromFile.SourceFile.CopyTo(outputFile, true); // Don't copy readonly attributes for output folder outputFile.Attributes = fromFile.SourceFile.Attributes & ~FileAttributes.ReadOnly; // Update statistics stat.Static = true; stat.OutputBytes += fromFile.Length; } } catch (Exception ex) { Site.Error(fromFile.SourceFile != null ? $"Unable to copy file [{fromFile.SourceFile}] to [{outputFile}]. Reason:{ex.GetReason()}" : $"Unable to copy file to [{outputFile}]. Reason:{ex.GetReason()}"); return(false); } finally { stat.OutputTime += clock.Elapsed; } return(true); }