/// <summary> /// 访问者模式相关 /// </summary> /// <param name="visitor"></param> public void Accept(IFileVisitor visitor) { foreach (var item in this._childList) { item.Accept(visitor); } visitor.Visit(this); }
/// <summary> /// Walk through a directory tree start with a root file, and performs <see cref="IFileVisitor.Visit"/> on each walked file /// </summary> /// <param name="fileSystemInfo">the root file</param> /// <param name="visitor">a visitor pattern</param> /// <exception cref="DirectoryNotFoundException"></exception> /// <exception cref="SecurityException"></exception> /// <exception cref="UnauthorizedAccessException"></exception> public static void WalkFileTree(this FileSystemInfo fileSystemInfo, IFileVisitor visitor) { switch (fileSystemInfo) { case FileInfo file: visitor.Visit(file); return; case DirectoryInfo directoryInfo: { // walk thru directories var dirRemains = new Stack <DirectoryInfo>(); if (!directoryInfo.Exists) { throw new DirectoryNotFoundException(directoryInfo.FullName); } dirRemains.Push(directoryInfo); while (dirRemains.Any()) { var toWalk = dirRemains.Pop(); foreach (var fileInfo in toWalk.GetFiles()) { visitor.Visit(fileInfo); } foreach (var subDirectory in toWalk.GetDirectories()) { dirRemains.Push(subDirectory); } } return; } default: throw new ArgumentException($"parameter {nameof(fileSystemInfo)} must be one of {{{nameof(FileInfo)}, {nameof(DirectoryInfo)}}}"); } }
public static IFileVisitor Walk(string root, IFileVisitor visitor) { if (root == null) { throw new ArgumentNullException(nameof(root)); } if (visitor == null) { throw new ArgumentNullException(nameof(visitor)); } if (!System.IO.Directory.Exists(root)) { throw new ArgumentException($""); } var nodes = new Stack <Node>(20); nodes.Push(new Node(root)); VisitResult result; while (nodes.Count > 0) { Node currentNode = nodes.Peek(); if (currentNode.IsFinished) { nodes.Pop(); result = visitor.PostDirectoryVisit(currentNode.Directory); if (VisitResult.Terminate == result) { return(visitor); } } currentNode.IsFinished = true; bool skipSubDirectories = false; bool skipFiles = false; result = visitor.PreDirectoryVisit(currentNode.Directory); switch (result) { case VisitResult.Terminate: visitor.PostDirectoryVisit(currentNode.Directory); return(visitor); case VisitResult.Return: skipSubDirectories = true; skipFiles = true; break; case VisitResult.SkipDirectories: skipSubDirectories = true; break; case VisitResult.SkipFiles: skipFiles = true; break; } if (!skipFiles) { string[] files = System.IO.Directory.GetFiles(currentNode.Directory); for (int i = 0; i < files.Length && !skipFiles; ++i) { result = visitor.VisitFile(files[i]); switch (result) { case VisitResult.Terminate: visitor.PostDirectoryVisit(currentNode.Directory); return(visitor); case VisitResult.Return: skipSubDirectories = true; skipFiles = true; break; case VisitResult.SkipDirectories: skipSubDirectories = true; break; case VisitResult.SkipFiles: skipFiles = true; break; } } } if (!skipSubDirectories) { string[] subDirs = System.IO.Directory.GetDirectories(currentNode.Directory); foreach (var subDir in subDirs) { nodes.Push(new Node(subDir)); } } } return(visitor); }
/// <summary> /// 访问者模式相关 /// </summary> /// <param name="visitor"></param> public void Accept(IFileVisitor visitor) { visitor.Visit(this); }