lith 3 years ago
parent
commit
bac98c0044

+ 0 - 89
FileZip/Cmd/Compression.cs

@@ -1,89 +0,0 @@
-using SharpCompress.Common;
-using SharpCompress.Writers;
-using System.IO;
-using Vit.ConsoleUtil;
-
-namespace FileZip.Cmd
-{
-    public class Compression
-    {
-
-        #region zip
-        [Command("zip")]
-        [Remarks("压缩为gzip文件。参数说明:")]
-        [Remarks("-i[--input] 待压缩目录 例如 \"/data/a\"")]
-        [Remarks("-o[--output] 压缩后文件名(若不指定,加压到压缩文件夹所在目录),例如 \"/data/a.zip\"")]
-        [Remarks("示例: zip -i \"/data/a\" -o \"/data/a.zip\" ")]
-        public static void zip(string[] args)
-        {
-            compression(args);
-        }
-        #endregion
-         
-
-
-
-        #region compression
-        public static void compression(string[] args)
-        {
-
-            ArchiveType archiveType;
-            CompressionType compressionType;
-            string fileSuffix;
-
-            #region (x.1) get arg
-
-            switch (args[0]) 
-            {
-                //case "gzip": archiveType = ArchiveType.GZip; compressionType = CompressionType.GZip; fileSuffix = "gz"; break;
-                //case "rar": archiveType = ArchiveType.Rar; compressionType = CompressionType.Deflate; fileSuffix = "rar"; break;
-                //case "7z": archiveType = ArchiveType.SevenZip; compressionType = CompressionType.de; fileSuffix = "7z"; break;
-                //case "tar": archiveType = ArchiveType.Tar; compressionType = CompressionType.GZip; fileSuffix = "tar"; break;
-                case "zip": archiveType = ArchiveType.Zip; compressionType = CompressionType.Deflate; fileSuffix = "zip"; break;
-                default: return;
-            }
-
-
-            string input = ConsoleHelp.GetArg(args, "-i") ?? ConsoleHelp.GetArg(args, "--input");
-            if (string.IsNullOrEmpty(input))
-            {
-                ConsoleHelp.Log("请指定待压缩目录");
-                return;
-            }
-
-            string output = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
-            if (string.IsNullOrEmpty(output))
-            {
-                output = input + "."+ fileSuffix;              
-            }
-            #endregion
-
- 
-
-
-            #region (x.2) 开始压缩
-
-            ConsoleHelp.Log("开始压缩");
-            ConsoleHelp.Log("待压缩文件:" + input);
-            ConsoleHelp.Log("压缩后文件名:" + output);
-
-            var writerOptions=new WriterOptions(compressionType);
-            writerOptions.ArchiveEncoding.Default = System.Text.Encoding.GetEncoding("utf-8");
-
-            using (var fileStream = File.OpenWrite(output))
-            using (var writer = WriterFactory.Open(fileStream, archiveType, writerOptions))
-            {               
-                writer.WriteAll(input, "*", SearchOption.AllDirectories);           
-            }
-
-            #endregion
-
-            ConsoleHelp.Log("文件压缩成功!!!");
-        }
-
-        #endregion
-
-
-
-    }
-}

+ 0 - 143
FileZip/Cmd/Un7z.cs

@@ -1,143 +0,0 @@
-using SharpCompress.Archives;
-using SharpCompress.Common;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Vit.ConsoleUtil;
-
-namespace FileZip.Cmd
-{
-    public class Un7z
-    {
-
-
-        #region un7z
-        
-        [Command("un7z")]
-        [Remarks("解压7z文件。参数说明:")]
-        [Remarks("-i[--input] 待解压文件 例如 \"/data/a.7z.001\"")]
-        [Remarks("-o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)")]
-        [Remarks("-m[--mute] 若指定,则不输出解压的文件(夹)信息")]
-        [Remarks("-mf[--mutefile] 若指定,则不输出解压的文件信息")]
-        [Remarks("示例: un7z -i \"/data/a.7z\" -o \"/data/out\" --mute ")]
-        public static void un7z(string[] args)
-        {
-            #region (x.1) get arg
-            string  input = ConsoleHelp.GetArg(args, "-i") ?? ConsoleHelp.GetArg(args, "--input");
-            if (string.IsNullOrEmpty(input))
-            {
-                ConsoleHelp.Log("请指定待解压文件");
-                return;
-            }
-
-            string output = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
-            if (string.IsNullOrEmpty(output))
-            {
-                //var directory = Path.GetDirectoryName(input);
-                //output = Path.Combine(directory,Path.GetFileNameWithoutExtension(input));
-                //if (output == input) 
-                //{
-                //    output = directory;
-                //}
-                output = Path.GetDirectoryName(input);
-
-                //ConsoleHelp.Log("请指定输出目录");
-                //return;
-            }
-            Directory.CreateDirectory(output);
-
-            bool printFile = (
-                (ConsoleHelp.GetArg(args, "-m") == null && ConsoleHelp.GetArg(args, "--mute") == null )
-             &&(ConsoleHelp.GetArg(args, "-mf") == null && ConsoleHelp.GetArg(args, "--mutefile") == null)  );
-
-            bool printDirectory = (ConsoleHelp.GetArg(args, "-m") == null && ConsoleHelp.GetArg(args, "--mute") == null);
-            #endregion
-
-            bool inputFileIsTemp = false;
-
-
-            try
-            {
-                #region (x.2)若为压缩分卷文件则合并到临时文件
-                {
-                    var extension = Path.GetExtension(input).TrimStart('.');
-                    if (int.TryParse(extension, out _))
-                    {
-                        var fileSearch = Path.Combine(Path.GetDirectoryName(input), Path.GetFileNameWithoutExtension(input) + ".*");
-
-                        input= Path.Combine(Path.GetDirectoryName(input),"tmp_"+ Path.GetFileNameWithoutExtension(input) + ".tmp");
-                      
-                        inputFileIsTemp = true;
-                        var cmd = new List<string>() { "marge" };
-                        cmd.AddRange(new[] { "-i", fileSearch });
-                        cmd.AddRange(new[] { "-o", input });                        
-                        Marge.marge(cmd.ToArray());
-                    }
-                }
-                #endregion
-
-
-
-                #region (x.3) 开始解压
-
-                ConsoleHelp.Log("开始解压");
-                ConsoleHelp.Log("待解压文件:" + input);
-                ConsoleHelp.Log("输出目录:" + output);
-               
-                using (var archive = ArchiveFactory.Open(input))
-                {
-                    var sum = archive.Entries.Count();
-
-                    if (sum == 0)
-                    {
-                        ConsoleHelp.Log("压缩文件中没有文件");
-                        return;
-                    }
-
-                    int finished = 0;
-                    int step = sum / 100;
-                    int nextStep = step;
-                    foreach (var entry in archive.Entries)
-                    {
-                        finished++;
-
-                        if (finished >= nextStep)
-                        {
-                            nextStep += step;
-                            ConsoleHelp.Log($"[{ finished }/{sum} ] 已完成 { finished * 100 / sum }%");
-                        }
-
-                        if (entry.IsDirectory)
-                        {
-                            if (printDirectory) ConsoleHelp.Log($"[{ finished }/{sum} d]  " + entry.Key);                            
-                        }
-                        else
-                        {
-                            if (printFile) ConsoleHelp.Log($"[{ finished }/{sum} f]  " + entry.Key);                          
-                        }
-
-                        entry.WriteToDirectory(output, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
-                    }
-                }
-
-                #endregion
-            }
-            finally
-            {
-                if (inputFileIsTemp)
-                {
-                    ConsoleHelp.Log("删除临时文件:" + input);
-                    File.Delete(input);
-                }
-            }
-
-            ConsoleHelp.Log("文件解压成功!!!");
-        }
-
-        #endregion
-
- 
-
-
-    }
-}

+ 0 - 132
FileZip/Cmd/Unrar.cs

@@ -1,132 +0,0 @@
-using SharpCompress.Archives;
-using SharpCompress.Common;
-using SharpCompress.Readers;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Vit.ConsoleUtil;
-
-namespace FileZip.Cmd
-{
-    public class Unrar
-    {
-
-
-        #region unrar
-        
-        [Command("unrar")]
-        [Remarks("解压rar文件。参数说明:")]
-        [Remarks("-i[--input] 待解压文件 例如 \"/data/a.rar.001\"")]
-        [Remarks("-o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)")]
-        [Remarks("-m[--mute] 若指定,则不输出解压的文件(夹)信息")]
-        [Remarks("-mf[--mutefile] 若指定,则不输出解压的文件信息")]
-        [Remarks("示例: unrar -i \"/data/a.rar\" -o \"/data/out\" --mute ")]
-        public static void Cmd_un7z(string[] args)
-        {
-            #region (x.1) get arg
-            string  input = ConsoleHelp.GetArg(args, "-i") ?? ConsoleHelp.GetArg(args, "--input");
-            if (string.IsNullOrEmpty(input))
-            {
-                ConsoleHelp.Log("请指定待解压文件");
-                return;
-            }
-
-            string output = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
-            if (string.IsNullOrEmpty(output))
-            {
-                //var directory = Path.GetDirectoryName(input);
-                //output = Path.Combine(directory, Path.GetFileNameWithoutExtension(input));
-                //if (output == input)
-                //{
-                //    output = directory;
-                //}
-                output = Path.GetDirectoryName(input);
-
-                //ConsoleHelp.Log("请指定输出目录");
-                //return;
-            }
-            Directory.CreateDirectory(output);
-
-            bool printFile = (
-                (ConsoleHelp.GetArg(args, "-m") == null && ConsoleHelp.GetArg(args, "--mute") == null )
-             &&(ConsoleHelp.GetArg(args, "-mf") == null && ConsoleHelp.GetArg(args, "--mutefile") == null)  );
-
-            bool printDirectory = (ConsoleHelp.GetArg(args, "-m") == null && ConsoleHelp.GetArg(args, "--mute") == null);
-            #endregion
-
-            bool inputFileIsTemp = false;
-
-
-            try
-            {
-                #region (x.2)若为压缩分卷文件则合并到临时文件
-                {
-                    var extension = Path.GetExtension(input).TrimStart('.');
-                    if (int.TryParse(extension, out _))
-                    {
-                        var fileSearch = Path.Combine(Path.GetDirectoryName(input), Path.GetFileNameWithoutExtension(input) + ".*");
-
-                        input= Path.Combine(Path.GetDirectoryName(input),"tmp_"+ Path.GetFileNameWithoutExtension(input) + ".tmp");
-                      
-                        inputFileIsTemp = true;
-                        var cmd = new List<string>() { "marge" };
-                        cmd.AddRange(new[] { "-i", fileSearch });
-                        cmd.AddRange(new[] { "-o", input });                        
-                        Marge.marge(cmd.ToArray());
-                    }
-                }
-                #endregion
-
-
-
-                #region (x.3) 开始解压
-
-                ConsoleHelp.Log("开始解压");
-                ConsoleHelp.Log("待解压文件:" + input);
-                ConsoleHelp.Log("输出目录:" + output);
-                using (Stream stream = File.OpenRead(input))
-                using (var reader = ReaderFactory.Open(stream))
-                {
-                    int fileCount = 0;
-                    int directoryCount = 0;              
-                    while (reader.MoveToNextEntry())
-                    {
-                        var entry = reader.Entry;                
-
-                        if (entry.IsDirectory)
-                        {
-                            directoryCount++;
-                            if (printDirectory) ConsoleHelp.Log($"[{ fileCount }-{directoryCount} d]: " + entry.Key);
-                        }
-                        else
-                        {
-                            fileCount++;
-                            if (printFile) ConsoleHelp.Log($"[{ fileCount }-{directoryCount} f]: " + entry.Key);
-                            reader.WriteEntryToDirectory(output, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
-                        }
-                    }
-                }
- 
-
-                #endregion
-            }
-            finally
-            {
-                if (inputFileIsTemp)
-                {
-                    ConsoleHelp.Log("删除临时文件:" + input);
-                    File.Delete(input);
-                }
-            }
-
-            ConsoleHelp.Log("文件解压成功!!!");
-        }
-
-        #endregion
-
-
- 
-
-
-    }
-}

+ 112 - 10
FileZip/Cmd/Unzip.cs

@@ -1,8 +1,5 @@
-using SharpCompress.Archives;
-using SharpCompress.Common;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.IO;
-using System.Linq;
 using Vit.ConsoleUtil;
 
 namespace FileZip.Cmd
@@ -14,15 +11,120 @@ namespace FileZip.Cmd
         #region unzip
         
         [Command("unzip")]
-        [Remarks("解压zip文件。参数说明:")]
+        [Remarks("解压zip文件。若为分卷(后缀为数字 如.001)则先合并文件再解压")]
+        [Remarks("支持格式: zip,gz,bzip2,tar,rar,lzip,xz,7zip,7z")]
+        [Remarks("参数说明:")]
         [Remarks("-i[--input] 待解压文件 例如 \"/data/a.zip.001\"")]
         [Remarks("-o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)")]
-        [Remarks("-m[--mute] 若指定,则不输出解压的文件(夹)信息")]
-        [Remarks("-mf[--mutefile] 若指定,则不输出解压的文件信息")]
-        [Remarks("示例: unzip -i \"/data/a.zip\" -o \"/data/out\" --mute ")]
+        [Remarks("-p[--progress] 进度信息间隔。如0.1代表进度每增加10%,提示一次。默认0.1")]
+        [Remarks("-f[--file] 若指定,则输出每一个文件信息")]
+        [Remarks("-d[--dir] 若指定,则输出每一个文件夹信息")]
+        [Remarks("示例: unzip -i \"/data/a.zip\" -o \"/data/out\" -p 0.1 -f -d ")]
         public static void unzip(string[] args)
-        {          
-            Un7z.un7z(args);
+        {
+            #region (x.1) get arg
+            string input = ConsoleHelp.GetArg(args, "-i") ?? ConsoleHelp.GetArg(args, "--input");
+            if (string.IsNullOrEmpty(input))
+            {
+                ConsoleHelp.Log("请指定待解压文件");
+                return;
+            }
+
+            string output = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
+            if (string.IsNullOrEmpty(output))
+            {
+                output = Path.GetDirectoryName(input);
+            }
+            Directory.CreateDirectory(output);
+
+            float? progress = null;
+            string strProgress = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
+            if (strProgress == "")
+            {
+                progress = 0.1f;
+            } else if (strProgress != null) 
+            {
+                if (float.TryParse(strProgress, out var pro) && pro>0 & pro<=1) 
+                {
+                    progress = pro;
+                }
+            }
+
+            bool printFile = !(ConsoleHelp.GetArg(args, "-f") == null && ConsoleHelp.GetArg(args, "--file") == null);
+
+            bool printDirectory = !(ConsoleHelp.GetArg(args, "-d") == null && ConsoleHelp.GetArg(args, "--dir") == null);
+            #endregion
+
+            bool inputFileIsTemp = false;
+
+
+            try
+            {
+                #region (x.2)若为压缩分卷文件则合并到临时文件
+                {
+                    var extension = Path.GetExtension(input).TrimStart('.');
+                    if (int.TryParse(extension, out _))
+                    {
+                        var fileSearch = Path.Combine(Path.GetDirectoryName(input), Path.GetFileNameWithoutExtension(input) + ".*");
+
+                        input = Path.Combine(Path.GetDirectoryName(input), "tmp_" + Path.GetFileNameWithoutExtension(input) + ".tmp");
+
+                        inputFileIsTemp = true;
+                        var cmd = new List<string>() { "marge" };
+                        cmd.AddRange(new[] { "-i", fileSearch });
+                        cmd.AddRange(new[] { "-o", input });
+                        Marge.marge(cmd.ToArray());
+                    }
+                }
+                #endregion
+
+
+
+                #region (x.3) 开始解压
+
+                ConsoleHelp.Log("开始解压");
+                ConsoleHelp.Log("待解压文件:" + input);
+                ConsoleHelp.Log("输出目录:" + output);
+
+
+                var unpack = new App.Logical.FileUnpack
+                {
+                    inputPath = input,
+                    outputPath = output
+                };
+                
+
+                if (printFile) 
+                {
+                    unpack.OnFile = (int sumCount, int curCount, string fileName) => ConsoleHelp.Log($"[{ curCount }/{sumCount} f]  " + fileName); 
+                }
+
+                if (printDirectory)
+                {
+                    unpack.OnDir = (int sumCount, int curCount, string fileName) => ConsoleHelp.Log($"[{ curCount }/{sumCount} d]  " + fileName);
+                }
+
+                if (progress != null)
+                {
+                    unpack.progressStep = progress.Value;
+                    unpack.OnProgress = (float pro, int sumCount, int curCount) => { ConsoleHelp.Log($"[{curCount}/{sumCount}] 已完成 { pro * 100 } %"); };
+                }
+
+                unpack.Unpack();
+
+
+                ConsoleHelp.Log("文件解压成功!!!");
+
+                #endregion
+            }
+            finally
+            {
+                if (inputFileIsTemp)
+                {
+                    ConsoleHelp.Log("删除临时文件:" + input);
+                    File.Delete(input);
+                }
+            }
         }
         #endregion
 

+ 96 - 0
FileZip/Cmd/Zip.cs

@@ -0,0 +1,96 @@
+using System.IO;
+using Vit.ConsoleUtil;
+
+namespace FileZip.Cmd
+{
+    public class Zip
+    {
+
+
+        #region zip
+        
+        [Command("zip")]
+        [Remarks("压缩文件(夹)")]
+        [Remarks("支持格式: .zip, .gz, .tar")]
+        [Remarks("参数说明:")]
+        [Remarks("-i[--input] 待压缩文件(夹),例如 \"/data/a.txt\" \"/data/files\"")]
+        [Remarks("-o[--output] 压缩输出文件m,使用后缀指定格式压缩,(若不指定,输出到待压缩文件所在目录)")]
+        [Remarks("-p[--progress] 进度信息间隔。如0.1代表进度每增加10%,提示一次。默认0.1")]
+        [Remarks("-f[--file] 若指定,则输出每一个文件信息")]
+        [Remarks("示例: zip -i \"/data/files\" -o \"/data/files.zip\" -p 0.1 -f")]
+        public static void zip(string[] args)
+        {
+            #region (x.1) get arg
+            string input = ConsoleHelp.GetArg(args, "-i") ?? ConsoleHelp.GetArg(args, "--input");
+            if (string.IsNullOrEmpty(input))
+            {
+                ConsoleHelp.Log("请指定待压缩文件(夹)");
+                return;
+            }
+
+            string output = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
+            if (string.IsNullOrEmpty(output))
+            {
+                output = Path.GetDirectoryName(input)+".zip";
+            }
+            Directory.CreateDirectory(Path.GetDirectoryName(output));
+
+            float? progress = null;
+            string strProgress = ConsoleHelp.GetArg(args, "-o") ?? ConsoleHelp.GetArg(args, "--output");
+            if (strProgress == "")
+            {
+                progress = 0.1f;
+            } else if (strProgress != null) 
+            {
+                if (float.TryParse(strProgress, out var pro) && pro>0 & pro<=1) 
+                {
+                    progress = pro;
+                }
+            }
+
+            bool printFile = !(ConsoleHelp.GetArg(args, "-f") == null && ConsoleHelp.GetArg(args, "--file") == null);
+            #endregion
+
+
+            #region (x.2) 开始解压
+
+            ConsoleHelp.Log("开始压缩");
+            ConsoleHelp.Log("待压缩文件(夹):" + input);
+            ConsoleHelp.Log("压缩后文件:" + output);
+
+
+            var pack = new App.Logical.FilePack
+            {
+                inputPath = input,
+                outputPath = output
+            };
+
+
+            if (printFile)
+            {
+                pack.OnFile = (int sumCount, int curCount, string fileName) => ConsoleHelp.Log($"[{ curCount }/{sumCount} f]  " + fileName);
+            }
+
+            
+
+            if (progress != null)
+            {
+                pack.progressStep = progress.Value;
+                pack.OnProgress = (float pro, int sumCount, int curCount) => { ConsoleHelp.Log($"[{curCount}/{sumCount}] 已完成 { pro * 100 } %"); };
+            }
+
+            pack.Pack();
+
+
+            ConsoleHelp.Log("文件压缩成功!!!");
+
+            #endregion
+
+        }
+        #endregion
+
+
+
+
+    }
+}

+ 16 - 12
FileZip/FileZip.csproj

@@ -1,17 +1,21 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp2.1</TargetFramework>
-    <Version>1.3.346</Version>
-    <Authors>Lith</Authors>
-    <Description>https://github.com/serset/FileZip</Description>
-  </PropertyGroup>
+	<PropertyGroup>
+		<OutputType>Exe</OutputType>
+		<TargetFramework>netcoreapp2.1</TargetFramework>
+		<Version>1.4-temp</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>文件加解压工具</Description>
+		<PackageProjectUrl>https://github.com/serset/FileZip</PackageProjectUrl>
+	</PropertyGroup>
+
+
+	<ItemGroup>
+		<PackageReference Include="sharpcompress" Version="0.28.3" />
+	</ItemGroup>
 
-  
-  <ItemGroup>
-    <PackageReference Include="sharpcompress" Version="0.25.1" />  
-  </ItemGroup>
- 
 
 </Project>

+ 220 - 0
FileZip/Logical/FilePack.cs

@@ -0,0 +1,220 @@
+#region << 版本注释 - v2 >>
+/*
+ * ========================================================================
+ * 版本:v2
+ * 时间:2021-06-09
+ * 作者:Lith   
+ * 邮箱:serset@yeah.net
+ * ========================================================================
+*/
+#endregion
+
+using System;
+using System.Linq;
+using SharpCompress.Common;
+using System.IO;
+using SharpCompress.Writers;
+using SharpCompress.Writers.Tar;
+using SharpCompress.Writers.GZip;
+
+namespace App.Logical
+{
+    /*    
+     
+ 
+
+     */
+    public class FilePack
+    {
+
+        const int stepMaxEntityCount = 10000;
+
+
+
+        /// <summary>
+        ///  是否可压缩。支持格式: .zip, .gz, .tar
+        /// </summary>
+        /// <param name="filePath"> 如  "a.zip"</param>
+        /// <returns></returns>
+        public static bool Supported(string filePath)
+        {
+            var format = Path.GetExtension(filePath)?.ToLower();
+            return new[] { ".zip", ".gz", ".tar" }.Any(f => f == format);
+        }
+
+
+        public FilePack()
+        {
+           
+        }
+
+
+        /// <summary>
+        /// 可为文件 或 文件夹
+        /// </summary>
+        public string inputPath;
+       
+        /// <summary>
+        /// 输出文件,通过文件后缀绝对压缩方式
+        /// </summary>
+        public string outputPath;
+
+ 
+
+        
+       
+        public void Pack()
+        {     
+
+            var format = Path.GetExtension(inputPath)?.ToLower();
+
+
+            if (new[] { ".zip", ".gz", ".tar" }.Any(f => f == format))
+            {
+                PackByWriter();
+                return;
+            }           
+            throw new InvalidOperationException("Cannot Support file format.  Supported Formats: .zip, .gz, .tar ");
+
+        }
+
+        public int sumEntityCount;
+        public int fileCount;
+
+
+        /// <summary>
+        ///  调用OnProgress的步骤(默认0.1)
+        /// </summary>
+        public float progressStep = 0.1f;
+        /// <summary>
+        ///  OnProgress = (float progress,int sumCount,int curCount)=>{ };
+        /// </summary>
+        public Action<float, int, int> OnProgress;
+
+
+        /// <summary>
+        ///  OnFile = (int sumCount,int curCount,string fileName)=>{ };
+        /// </summary>
+        public Action<int, int,string> OnFile;
+
+        ///// <summary>
+        /////  OnDir = (int sumCount,int curCount,string fileName)=>{ };
+        ///// </summary>
+        //public Action<int, int, string> OnDir;
+ 
+
+
+
+        /// <summary>
+        /// Supported Reader Formats: Zip, GZip, Tar
+        /// </summary>
+        public void PackByWriter()
+        {
+            fileCount = 0;
+            sumEntityCount = 0;
+
+            ArchiveType archiveType;
+            WriterOptions writerOptions; 
+    
+            switch (Path.GetExtension(outputPath)?.ToLower())
+            {
+                case ".gz":
+                    archiveType = ArchiveType.GZip; 
+                    writerOptions = new GZipWriterOptions(); 
+                    break;
+                case ".tar":
+                    archiveType = ArchiveType.Tar;
+                    writerOptions = new TarWriterOptions(CompressionType.None, true); 
+                    break;
+                case ".zip": 
+                    archiveType = ArchiveType.Zip; 
+                    writerOptions = new WriterOptions(CompressionType.Deflate);  //CompressionType.BZip2  CompressionType.None CompressionType.LZMA CompressionType.PPMd
+                    break;
+                default: throw new InvalidOperationException("Cannot Support file format.  Supported Formats: .zip, .gz, .tar ");
+            }
+
+
+            //writerOptions.ArchiveEncoding.Default = System.Text.Encoding.UTF8;
+            //readOptions.ArchiveEncoding.Default = System.Text.Encoding.Default;
+            writerOptions.ArchiveEncoding.Default = System.Text.Encoding.GetEncoding("GB2312");
+
+
+
+            if (File.Exists(inputPath))
+            {
+                //压缩单个文件
+                sumEntityCount = 1;
+
+                #region (x.x.2)压缩
+                Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
+                using (var fileStream = File.OpenWrite(outputPath))
+                using (var writer = WriterFactory.Open(fileStream, archiveType, writerOptions))
+                {               
+                    var directoryLength = inputPath.Length;
+
+                    var relativePath = Path.GetFileName(inputPath);
+                    writer.Write(relativePath, inputPath);
+
+                    OnFile?.Invoke(1, 1, relativePath);
+                    OnProgress?.Invoke(1.0f, 1, 1);
+                }
+                #endregion
+            }
+            else 
+            {
+                //压缩文件夹
+
+                #region (x.x.1)获取文件(夹)总个数
+                var enumerable = Directory.EnumerateFiles(inputPath, "*", SearchOption.AllDirectories);
+                sumEntityCount = enumerable.Count();
+                #endregion
+
+                #region (x.x.2)压缩
+                Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
+                using (var fileStream = File.OpenWrite(outputPath))
+                using (var writer = WriterFactory.Open(fileStream, archiveType, writerOptions))
+                {
+                    int importedEntityCount = 0;
+                    int step = Math.Min((int)(sumEntityCount * progressStep), stepMaxEntityCount);
+                    int nextStep = step;
+
+
+                    var directoryLength = inputPath.Length;
+                    foreach (var file in enumerable)
+                    {
+                        var relativePath = file.Substring(directoryLength);
+                        writer.Write(relativePath, file);
+
+                        importedEntityCount++;
+
+
+                        //if (entry.IsDirectory)
+                        //{
+                        //    dirCount++;
+                        //    OnDir?.Invoke(sumEntityCount, importedEntityCount, relativePath);
+                        //}
+                        //else
+                        {
+                            fileCount++;
+                            OnFile?.Invoke(sumEntityCount, importedEntityCount, relativePath);
+                        }
+
+                        if (importedEntityCount >= nextStep)
+                        {
+                            nextStep = Math.Min(sumEntityCount, nextStep + step);
+                            OnProgress?.Invoke(1.0f * importedEntityCount / sumEntityCount, sumEntityCount, importedEntityCount);
+                        }
+
+                    }
+                }
+
+                #endregion
+
+            }
+
+        }
+
+    }
+}
+
+ 

+ 281 - 0
FileZip/Logical/FileUnpack.cs

@@ -0,0 +1,281 @@
+#region << 版本注释 - v2 >>
+/*
+ * ========================================================================
+ * 版本:v2
+ * 时间:2021-06-09
+ * 作者:Lith   
+ * 邮箱:serset@yeah.net
+ * ========================================================================
+*/
+#endregion
+
+using System;
+using System.Linq;
+using SharpCompress.Archives;
+using SharpCompress.Common;
+using System.IO;
+using SharpCompress.Readers;
+
+namespace App.Logical
+{
+    /*    
+     
+        new App.Logical.FileUnpack
+        {
+            inputPath = @"T:\temp\blue-sh.zip",
+            outputPath = @"T:\temp\blue-sh",
+            OnFile = (int sumCount,int curCount,string fileName)=>{ },
+            OnDir = (int sumCount,int curCount,string fileName)=>{ }, 
+            OnProgress = (float progress, int sumCount, int curCount) => { Console.WriteLine($"[{curCount}/{sumCount}]:"+ progress);  }                
+        }.Unpack();  
+
+     */
+    public class FileUnpack
+    {
+
+        const int stepMaxEntityCount = 10000;
+
+        ReaderOptions readOptions = new ReaderOptions();
+        ExtractionOptions extractionOptions = new ExtractionOptions() { ExtractFullPath = true, Overwrite = true };
+
+
+        /// <summary>
+        ///  是否可解压。支持格式: zip,gz,bzip2,tar,rar,lzip,xz,7zip,7z
+        /// </summary>
+        /// <param name="filePath"> 如  "a.zip"</param>
+        /// <returns></returns>
+        public static bool Supported(string filePath)
+        {
+            var format = Path.GetExtension(filePath)?.ToLower();
+            return new[] { ".zip", ".gz", ".bzip2", ".tar", ".rar", ".lzip", ".xz", ".7zip", ".7z" }.Any(f => f == format);
+        }
+
+
+        public FileUnpack()
+        {
+            //readOptions.ArchiveEncoding.Default = System.Text.Encoding.UTF8;
+            //readOptions.ArchiveEncoding.Default = System.Text.Encoding.Default;
+            readOptions.ArchiveEncoding.Default = System.Text.Encoding.GetEncoding("GB2312");
+        }
+
+
+
+        public string inputPath;
+        public string outputPath;
+        
+       
+        public void Unpack()
+        {
+            dirCount = 0;
+            fileCount = 0;
+            sumEntityCount = 0;
+
+            var format = Path.GetExtension(inputPath)?.ToLower();
+
+
+            //Supported Reader Formats: Zip, GZip, BZip2, Tar, Rar, LZip, XZ
+            if (new[] { ".zip", ".gz", ".bzip2", ".tar", ".rar", ".lzip", ".xz" }.Any(f => f == format))
+            {
+                UnpackByReader();
+                return;
+            }
+
+            //Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip
+            if (new[] { ".zip", ".gz", ".tar", ".rar", ".7z" }.Any(f => f == format))
+            {
+                UnpackByEntry();
+                return;
+            }
+
+            throw new InvalidOperationException("Cannot Support file format.  Supported Formats: Zip, GZip, BZip2, Tar, Rar, LZip, XZ, 7Zip, 7Z");
+
+        }
+
+        public int sumEntityCount;
+
+        public int fileCount;
+        public int dirCount;
+
+
+        /// <summary>
+        ///  调用OnProgress的步骤(默认0.1)
+        /// </summary>
+        public float progressStep = 0.1f;
+        /// <summary>
+        ///  OnProgress = (float progress,int sumCount,int curCount)=>{ };
+        /// </summary>
+        public Action<float, int, int> OnProgress;
+
+
+        /// <summary>
+        ///  OnFile = (int sumCount,int curCount,string fileName)=>{ };
+        /// </summary>
+        public Action<int, int,string> OnFile;
+
+        /// <summary>
+        ///  OnDir = (int sumCount,int curCount,string fileName)=>{ };
+        /// </summary>
+        public Action<int, int, string> OnDir;
+
+        /// <summary>
+        /// Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip
+        /// </summary>
+        public void UnpackByEntry()
+        {
+            //System.IO.Compression.ZipFile.ExtractToDirectory(@"xxx.zip", @"xx\tttt", System.Text.CodePagesEncodingProvider.Instance.GetEncoding("GB2312"), true);
+
+            dirCount = 0;
+            fileCount = 0;
+            sumEntityCount = 0;
+
+            using (var archive = ArchiveFactory.Open(inputPath, readOptions))
+            {
+                sumEntityCount = archive.Entries.Count();
+
+                if (sumEntityCount == 0)
+                {
+                    OnProgress?.Invoke(1, 0, 0);
+                    return;
+                }
+
+                int importedEntityCount = 0; 
+                int step = Math.Min((int)(sumEntityCount * progressStep), stepMaxEntityCount);
+                int nextStep = step;
+
+
+                //(法.1)流式读取
+                using (var reader = archive.ExtractAllEntries())
+                {
+                    while (reader.MoveToNextEntry())
+                    {
+                        var entry = reader.Entry;
+                        reader.WriteEntryToDirectory(outputPath, extractionOptions);
+
+                        importedEntityCount++;
+
+                        if (importedEntityCount >= nextStep)
+                        {
+                            nextStep = Math.Min(sumEntityCount, nextStep + step);
+                            OnProgress?.Invoke(1.0f * importedEntityCount / sumEntityCount, sumEntityCount, importedEntityCount);
+                        }
+
+                        if (entry.IsDirectory)
+                        {
+                            dirCount++;
+                            OnDir?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                        }
+                        else
+                        {
+                            fileCount++;
+                            OnFile?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                        }
+                    }
+                }
+                return;
+
+
+                //(法.2)
+                foreach (var entry in archive.Entries)
+                {
+                    entry.WriteToDirectory(outputPath, extractionOptions);
+
+                    importedEntityCount++;
+
+                    if (importedEntityCount >= nextStep)
+                    {
+                        nextStep = Math.Min(sumEntityCount, nextStep + step);
+                        OnProgress?.Invoke(1.0f * importedEntityCount / sumEntityCount, sumEntityCount, importedEntityCount);
+                    }
+
+                    if (entry.IsDirectory)
+                    {
+                        dirCount++;
+                        OnDir?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                    }
+                    else
+                    {
+                        fileCount++;
+                        OnFile?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                    }
+                }
+            }
+        }
+
+
+
+        /// <summary>
+        /// Supported Reader Formats: Zip, GZip, BZip2, Tar, Rar, LZip, XZ
+        /// </summary>
+        public void UnpackByReader()
+        {
+            dirCount = 0;
+            fileCount = 0;
+            sumEntityCount = 0;
+
+            #region (x.1)获取文件(夹)总个数
+            using (Stream stream = File.OpenRead(inputPath))
+            using (var reader = ReaderFactory.Open(stream, readOptions))
+            {               
+                while (reader.MoveToNextEntry())
+                {
+                    sumEntityCount++;
+                }   
+            }
+
+            if (sumEntityCount == 0)
+            {
+                OnProgress?.Invoke(1, 0, 0);
+                return;
+            }
+            #endregion
+
+            #region (x.2)解压
+            using (Stream stream = File.OpenRead(inputPath))
+            using (var reader = ReaderFactory.Open(stream, readOptions))
+            {
+                int importedEntityCount = 0;
+                int step = Math.Min((int)(sumEntityCount * progressStep), stepMaxEntityCount);
+                int nextStep = step;
+
+                while (reader.MoveToNextEntry())
+                {
+                    var entry = reader.Entry;
+
+                    //if (entry.IsDirectory)
+                    //{
+                    //    reader.WriteEntryToDirectory(outputDirPath, extractionOptions);
+                    //}
+                    //else
+                    {
+                        reader.WriteEntryToDirectory(outputPath, extractionOptions);
+                    }
+
+                    importedEntityCount++;
+
+                    if (entry.IsDirectory)
+                    {
+                        dirCount++;
+                        OnDir?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                    }
+                    else
+                    {
+                        fileCount++;
+                        OnFile?.Invoke(sumEntityCount, importedEntityCount, entry.Key);
+                    }
+
+                    if (importedEntityCount >= nextStep)
+                    {
+                        nextStep = Math.Min(sumEntityCount, nextStep + step);
+                        OnProgress?.Invoke(1.0f * importedEntityCount / sumEntityCount, sumEntityCount, importedEntityCount);
+                    }
+                }
+            }
+            #endregion
+
+
+        }
+
+    }
+}
+
+ 

+ 2 - 8
FileZip/Program.cs

@@ -12,15 +12,9 @@ namespace Main
         public static void Main(string[] args)
         {
 
-            //var arg = new List<string>() { "un7z" };
-            //arg.AddRange(new[] { "-i", "T:\\temp\\tileset.7z.001" });
-            //arg.AddRange(new[] { "-o", "T:\\temp\\tileset" });
-            //args = arg.ToArray();
+            var arg = new List<string>() { "help" };
+            args = arg.ToArray();
 
-            //var arg = new List<string>() { "unrar" };
-            //arg.AddRange(new[] { "-i", "T:\\temp\\tileset.rar" });
-            //arg.AddRange(new[] { "-o", "T:\\temp\\tileset" });
-            //args = arg.ToArray();
 
             //var arg = new List<string>() { "unzip" };
             //arg.AddRange(new[] { "-i", "T:\\temp\\tileset.zip" });

+ 4 - 0
Publish/UpgradeLog.md

@@ -0,0 +1,4 @@
+# 2021-06-06
+解决压缩和解压时忽略文件夹的bug
+
+

+ 0 - 76
readme.md

@@ -1,76 +0,0 @@
-# FileZip
-> FileZip为net core2.1开发的文件加解压工具,包括 文件合并、加压(zip) 和 解压(unzip、un7z、unrar)等功能  
-> 运行环境 dotnet core 2.1
-
-## 1. demo
-``` bash
-# 查看帮助
-dotnet FileZip.dll
-
-# 合并文件
-dotnet FileZip.dll marge -i "E:\t 2" -o "E:\t 2.7z"
-
-# 解压7z文件到文件夹"E:\t\t2"
-dotnet FileZip.dll un7z -i "E:\t\m.7z" -o "E:\t\t2"
-```
-
-## 2. docker运行
-``` bash
-# 查看帮助
-docker run --rm -it serset/filezip
-
-
-# 解压7z文件m.7zd到文件夹 /root/docker/file/a
-cd /root/docker/file
-docker run --rm -it \
--v $PWD:/root/app/file  \
-serset/filezip  \
-dotnet FileZip.dll un7z \
-"-i" "/root/app/file/m.7z" \
-"-o" "/root/app/file/a"
-
-```
-
-## 3. 命令说明:
----------------
-help  
-帮助文档:  
--c[--command] 要查询的命令。若不指定则返回所有命令的文档。如 help  
-示例: help -c help  
----------------
-zip  
-压缩为gzip文件。参数说明:  
--i[--input] 待压缩目录 例如 "/data/a"  
--o[--output] 压缩后文件名(若不指定,加压到压缩文件夹所在目录),例如 "/data/a.zip"  
-示例: zip -i "/data/a" -o "/data/a.zip"  
----------------
-marge  
-合并文件。参数说明:  
--i[--input] 待合并的文件夹 或 文件查询字符串。 如 /data/a/1.7z.\*    
--o[--output] 合并后文件  
-示例: marge -i "/data/a" -o /data/a.7z  
----------------
-un7z  
-解压7z文件。参数说明:  
--i[--input] 待解压文件 例如 "/data/a.7z.001"  
--o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)  
--m[--mute] 若指定,则不输出解压的文件(夹)信息  
--mf[--mutefile] 若指定,则不输出解压的文件信息  
-示例: un7z -i "/data/a.7z" -o "/data/out" --mute  
----------------
-unrar  
-解压rar文件。参数说明:  
--i[--input] 待解压文件 例如 "/data/a.rar.001"  
--o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)  
--m[--mute] 若指定,则不输出解压的文件(夹)信息  
--mf[--mutefile] 若指定,则不输出解压的文件信息  
-示例: unrar -i "/data/a.rar" -o "/data/out" --mute  
----------------
-unzip  
-解压zip文件。参数说明:  
--i[--input] 待解压文件 例如 "/data/a.zip.001"  
--o[--output] 输出目录,(若不指定,则解压到压缩文件所在目录)  
--m[--mute] 若指定,则不输出解压的文件(夹)信息  
--mf[--mutefile] 若指定,则不输出解压的文件信息  
-示例: unzip -i "/data/a.zip" -o "/data/out" --mute  
----------------