From 01f395b326cb7f3bb515cba3495a4203c39991d5 Mon Sep 17 00:00:00 2001 From: Shingo Date: Sat, 27 Apr 2019 14:37:57 +0800 Subject: [PATCH] init --- App.config | 6 +++ Program.cs | 97 +++++++++++++++++++++++++++++++++++ Properties/AssemblyInfo.cs | 36 +++++++++++++ README.md | 5 ++ Runner.cs | 101 +++++++++++++++++++++++++++++++++++++ ShingoTree.csproj | 54 ++++++++++++++++++++ 6 files changed, 299 insertions(+) create mode 100644 App.config create mode 100644 Program.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 README.md create mode 100644 Runner.cs create mode 100644 ShingoTree.csproj diff --git a/App.config b/App.config new file mode 100644 index 0000000..00bfd11 --- /dev/null +++ b/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..36405b7 --- /dev/null +++ b/Program.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace ShingoTree +{ + class Program + { + static void Main(string[] args) + { + if(args.Length == 0) + { + PrintHelp(); + return; + } + + List pathes = new List(); + Runner runner = BuildRunner(args, pathes); + + if (pathes.Count == 0) + pathes.Add(Environment.CurrentDirectory); + + runner.Lookup(pathes); + } + + private static void PrintHelp() + { + Console.WriteLine("以图形显示驱动器或路径的文件夹结构。"); + Console.WriteLine(); + Console.WriteLine("SHINGOTREE [/F] [/O output [/V]] [path, ...]"); + Console.WriteLine(); + Console.WriteLine(" /F 显示每个文件夹中文件的名称。"); + Console.WriteLine(" /O 将结果输出到文件。"); + Console.WriteLine(" /V 显示当前进度。"); + Console.WriteLine(); + } + + private static Runner BuildRunner(string[] args, List pathes) + { + bool printFile = false, output = false, progress = false; + string outputFile = null; + + foreach (var arg in args) + { + switch (arg) + { + case "/F": + case "/f": + printFile = true; + break; + case "/O": + case "/o": + if (outputFile != null) + { + Console.WriteLine("参数错误,指定了多个输出文件。"); + return null; + } + output = true; + break; + case "/V": + case "/v": + progress = true; + break; + + default: + if (output) + { + output = false; + outputFile = arg; + } + else + { + pathes.Add(arg); + } + break; + } + } + + TextWriter outputStream; + if (outputFile == null) + { + progress = false; + outputStream = Console.Out; + } + else + outputStream = new StreamWriter(outputFile, false, Encoding.UTF8); + + return new Runner + { + printFile = printFile, + output = outputStream, + progress = progress, + }; + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fa964b0 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ShingoTree")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ShingoTree")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5b66317c-eda3-4bd1-818e-48a4b1bb64a1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9a9ed5 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +SHINGOTREE [/F] [/O output [/V]] [path, ...] + + /F Show files. + /O Output to file. + /V Show progress. \ No newline at end of file diff --git a/Runner.cs b/Runner.cs new file mode 100644 index 0000000..7b44b8d --- /dev/null +++ b/Runner.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace ShingoTree +{ + class Runner + { + public bool printFile; + public bool progress; + public TextWriter output; + + private double _progress; + private int _lastReportProgress; + + void LookUpDirectory(string path, string pprefix, double maxprog) + { + string[] directories = Directory.GetDirectories(path); + int dirLength = directories.Length; + + if (printFile) + { + string[] files = Directory.GetFiles(path); + if (files.Length > 0) + { + string prefix = pprefix + (dirLength > 0 ? "│ " : " "); + foreach (var file in files) + { + output.Write(prefix); + output.WriteLine(file.Substring(path.Length + 1)); + } + output.WriteLine(prefix); + } + } + + if (dirLength > 0) + { + double prog = _progress; + double progAdv = (maxprog - prog) / dirLength; + + int dirLengthM1 = dirLength - 1; + + if (dirLengthM1 > 0) + { + string prefix = pprefix + "├─"; + string subPrefix = pprefix + "│ "; + for (int i = 0; i < dirLengthM1; i++) + OutputDirectory(path, directories[i], prog += progAdv, prefix, subPrefix); + } + OutputDirectory(path, directories[dirLengthM1], prog + progAdv, + pprefix + "└─", pprefix + " "); + } + } + + void OutputDirectory(string path, string directory, double maxprog, string prefix, string subPrefix) + { + output.Write(prefix); + output.WriteLine(directory.Substring(path.Length + 1)); + LookUpDirectory(directory, subPrefix, maxprog); + ReportProgress(maxprog); + } + + void ReportProgress(double p) + { + const int PROGRESS_BAR_WIDTH = 70; + + if (progress) + { + int intProg = (int)(p * 1000); + if (intProg != _lastReportProgress) + { + _lastReportProgress = intProg; + Console.Write("\r["); + int w = (int)Math.Round(p * PROGRESS_BAR_WIDTH); + Console.Write(new string('=', w)); + Console.Write(new string(' ', PROGRESS_BAR_WIDTH - w)); + Console.Write("] " + p.ToString("#.0%")); + } + } + _progress = p; + } + + internal void Lookup(List pathes) + { + _progress = 0.0; + _lastReportProgress = 0; + int count = pathes.Count; + double maxprog = 0.0; + + for (int i = 0; i < count; i++) + { + string path = Path.GetFullPath(pathes[i]); + output.WriteLine(path); + maxprog += 1.0 / count; + LookUpDirectory(path, "", maxprog); + ReportProgress(maxprog); + output.WriteLine(); + } + } + } +} diff --git a/ShingoTree.csproj b/ShingoTree.csproj new file mode 100644 index 0000000..eed1715 --- /dev/null +++ b/ShingoTree.csproj @@ -0,0 +1,54 @@ + + + + + Debug + AnyCPU + {5B66317C-EDA3-4BD1-818E-48A4B1BB64A1} + Exe + ShingoTree + ShingoTree + v4.6.1 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file