C# 文件压缩与解压缩

2 篇文章 0 订阅
2 篇文章 0 订阅

工具:ZipTool.exe

源码:ZipTool_src.zip

文件压缩、解压处理类,ZipTool.cs

using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tools
{
    /// <summary>
    /// 文件压缩zip()、解压缩unzip()
    /// </summary>
    public class ZipTool
    {
        /// <summary>
        /// 根据给的文件参数,自动进行压缩或解压缩操作
        /// </summary>
        public static void Process(String[] files, String Password = null)
        {
            if (files.Length > 0)
            {
                if (files.Length == 1 && (files[0].ToLower().EndsWith(".zip") || files[0].ToLower().EndsWith(".rar")))
                {
                    unzip(files[0], null, Password, null);                  // 解压缩
                }
                else
                {
                    String zipPath = Tools.getPathNoExt(files[0]) + ".zip";	// 以待压缩的第一个文件命名生成的压缩文件
                    String BaseDir = Tools.getParent(files[0]);				// 获取第一个文件的父路径信息
                    if (files.Length == 1)									// 若载入的为单个目录,则已当前目录作为基础路径
                    {
                        String file = files[0];
                        if (Directory.Exists(file)) BaseDir = file + "\\";
                    }

                    String[] subFiles = Tools.getSubFiles(files);			// 获取args对应的所有目录下的文件列表
                    zip(zipPath, BaseDir, subFiles, Password, null);		// 对载入的文件进行压缩操作
                }
            }
        }

        /// <summary>
        /// 压缩所有文件files为zip
        /// </summary>
        public static bool zipFiles(String[] files, String Password = null, String[] ignoreNames = null)
        {
            return zip(null, null, files, Password, ignoreNames);
        }

        /// <summary>
        /// 压缩指定的文件或文件夹为zip
        /// </summary>
        public static bool zip(String file, String Password = null, String[] ignoreNames = null)
        {
            return zip(null, null, new String[] { file }, Password, ignoreNames);
        }

        /// <summary>
        /// 判断fileName中是否含有ignoreNames中的某一项
        /// </summary>
        private static bool ContainsIgnoreName(String fileName, String[] ignoreNames)
        {
            if (ignoreNames != null && ignoreNames.Length > 0)
            {
                foreach (string name in ignoreNames)
                {
                    if (fileName.Contains(name)) return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 压缩所有文件files,为压缩文件zipFile, 以相对于BaseDir的路径构建压缩文件子目录,ignoreNames指定要忽略的文件或目录
        /// </summary>
        public static bool zip(String zipPath, String BaseDir, String[] files, String Password = null, String[] ignoreNames = null)
        {
            if (files == null || files.Length == 0) return false;
            if (zipPath == null || zipPath.Equals("")) zipPath = Tools.getPathNoExt(files[0]) + ".zip";	// 默认以第一个文件命名压缩文件
            if (BaseDir == null || BaseDir.Equals("")) BaseDir = Tools.getParent(files[0]);				// 默认以第一个文件的父目录作为基础路径
            Console.WriteLine("所有待压缩文件根目录:" + BaseDir);

            try
            {
                Tools.mkdirs(Tools.getParent(zipPath));         // 创建目标路径
                Console.WriteLine("创建压缩文件:" + zipPath);

                FileStream input = null;
                ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipPath));
                if (Password != null && !Password.Equals("")) zipStream.Password = Password;

                files = Tools.getSubFiles(files);               // 获取子目录下所有文件信息
                for (int i = 0; i < files.Length; i++)
                {
                    if (ContainsIgnoreName(files[i], ignoreNames)) continue;    // 跳过忽略的文件或目录

                    String entryName = Tools.relativePath(BaseDir, files[i]);
                    zipStream.PutNextEntry(new ZipEntry(entryName));
                    Console.WriteLine("添加压缩文件:" + entryName);

                    if (File.Exists(files[i]))                  // 读取文件内容
                    {
                        input = File.OpenRead(files[i]);
                        Random rand = new Random();
                        byte[] buffer = new byte[10240];
                        int read = 0;
                        while ((read = input.Read(buffer, 0, 10240)) > 0)
                        {
                            zipStream.Write(buffer, 0, read);
                        }
                        input.Close();
                    }
                }
                zipStream.Close();
                Console.WriteLine("文件压缩完成!");

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            return false;
        }

        /// <summary>
        /// 解压文件 到指定的路径,可通过targeFileNames指定解压特定的文件
        /// </summary>
        public static bool unzip(String zipPath, String targetPath = null, String Password = null, String[] targeFileNames = null)
        {
            if (File.Exists(zipPath))
            {
                if (targetPath == null || targetPath.Equals("")) targetPath = Tools.getPathNoExt(zipPath);
                Console.WriteLine("解压文件:" + zipPath);
                Console.WriteLine("解压至目录:" + targetPath);

                try
                {
                    ZipInputStream zipStream = null;
                    FileStream bos = null;

                    zipStream = new ZipInputStream(File.OpenRead(zipPath));
                    if (Password != null && !Password.Equals("")) zipStream.Password = Password;

                    ZipEntry entry = null;
                    while ((entry = zipStream.GetNextEntry()) != null)
                    {
                        if (targeFileNames != null && targeFileNames.Length > 0)                // 若指定了目标解压文件
                        {
                            if (!ContainsIgnoreName(entry.Name, targeFileNames)) continue;      // 跳过非指定的文件
                        }

                        String target = targetPath + "\\" + entry.Name;
                        if (entry.IsDirectory) Tools.mkdirs(target); // 创建目标路径
                        if (entry.IsFile)
                        {
                            Tools.mkdirs(Tools.getParent(target));

                            bos = File.Create(target);
                            Console.WriteLine("解压生成文件:" + target);

                            int read = 0;
                            byte[] buffer = new byte[10240];
                            while ((read = zipStream.Read(buffer, 0, 10240)) > 0)
                            {
                                bos.Write(buffer, 0, read);
                            }
                            bos.Flush();
                            bos.Close();
                        }
                    }
                    zipStream.CloseEntry();

                    Console.WriteLine("解压完成!");
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString()); ;
                }
            }
            return false;
        }

    }

}
Tools.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tools
{
    /// <summary>
    /// 通用功能函数
    /// </summary>
    public class Tools
    {
        /// <summary>
        /// 检测目录是否存在,若不存在则创建
        /// </summary>
        public static void mkdirs(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        /// <summary>
        /// 获取去除拓展名的文件路径
        /// </summary>
        public static String getPathNoExt(String path)
        {
            if (File.Exists(path)) return Directory.GetParent(path).FullName + "\\" + Path.GetFileNameWithoutExtension(path);
            else return Directory.GetParent(path).FullName + "\\" + Path.GetFileName(path);
        }

        /// <summary>
        /// 获取父目录的路径信息
        /// </summary>
        public static String getParent(String path)
        {
            return System.IO.Directory.GetParent(path).FullName + "\\";
        }


        /// <summary>
        /// 获取父目录的路径信息
        /// </summary>
        public static String getFileName(String path)
        {
            return System.IO.Path.GetFileName(path);
        }

        /// <summary>
        /// 获取filePath的相对于BaseDir的路径
        /// </summary>
        public static String relativePath(String BaseDir, String filePath)
        {
            String relativePath = "";
            if (filePath.StartsWith(BaseDir)) relativePath = filePath.Substring(BaseDir.Length);
            return relativePath;
        }


        //-----------------------------------------------------------------------------------------

        /// <summary>
        /// 获取paths路径下所有文件信息
        /// </summary>
        public static String[] getSubFiles(String[] Paths)
        {
            List<String> list = new List<String>();	        // paths路径下所有文件信息

            foreach (String path in Paths)
            {
                List<String> subFiles = getSubFiles(path);	// 获取路径path下所有文件列表信息
                list = ListAdd(list, subFiles);
            }

            String[] A = List2Array(list);					// 转化为数组形式

            return A;
        }

        /// <summary>
        /// 合并list1和list2到新的list
        /// </summary>
        public static List<String> ListAdd(List<String> list1, List<String> list2)
        {
            List<String> list = new List<String>();

            foreach (String path in list1) if (!list.Contains(path)) list.Add(path);
            foreach (String path in list2) if (!list.Contains(path)) list.Add(path);

            return list;
        }

        /// <summary>
        /// 获取file目录下所有文件列表
        /// </summary>
        public static List<String> getSubFiles(String file)
        {
            List<String> list = new List<String>();

            if (File.Exists(file))
            {
                if (!list.Contains(file)) list.Add(file);
            }

            if (Directory.Exists(file))
            {
                // 获取目录下的文件信息
                foreach (String iteam in Directory.GetFiles(file))
                {
                    if (!list.Contains(iteam)) list.Add(iteam);
                }

                // 获取目录下的子目录信息
                foreach (String iteam in Directory.GetDirectories(file))
                {
                    List<String> L = getSubFiles(iteam);	// 获取子目录下所有文件列表
                    foreach (String path in L)
                    {
                        if (!list.Contains(path)) list.Add(path);
                    }
                }

                // 记录当前目录
                if (Directory.GetFiles(file).Length == 0 && Directory.GetDirectories(file).Length == 0)
                {
                    if (!list.Contains(file)) list.Add(file + "\\");
                }
            }

            return list;
        }

        /// <summary>
        /// 转化list为数组
        /// </summary>
        public static String[] List2Array(List<String> list)
        {
            int size = (list == null ? 0 : list.Count);
            String[] A = new String[size];

            int i = 0;
            foreach (String S in list)
            {
                A[i++] = S;
            }

            return A;
        }

    }

}
Program.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZipTool.Properties;

namespace ZipTool
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。拖动待压缩或解压的文件至此应用,即可进行压缩或解压。\r\n通过cmd调用时,传参数PASS:***可指定密码
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args != null && args.Length > 0)
            {
                Depends.Export(args);   // 解压依赖dll
                AnalyseArgs(args);      // 解析参数信息
                process(Args, Password);// 执行压缩解压
            }
            else MessageBox.Show("拖动待压缩或解压的文件至此应用,即可进行压缩或解压。\r\n通过cmd调用时,传参数PASS:***可指定密码!");
        }

        /// <summary>
        /// 执行压缩解压逻辑
        /// </summary>
        private static void process(string[] args, string password)
        {
            // 执行逻辑
            if (args != null && args.Length > 0)
            {
                // 进行压缩、解压
                Tools.ZipTool.Process(Args, Password);

                 删除临时文件
                //deletFile("ICSharpCode.SharpZipLib.dll");
                //deletFile("Tools.dll");
                string[] files = new string[] { "ICSharpCode.SharpZipLib.dll", "Tools.dll" };
                AutoDelet.deletFiles(files);
            }
        }

        private static string Password = null;  // 压缩解压密码
        private static string[] Args = null;    // 其他参数
        /// <summary>
        /// 解析应用参数信息
        /// </summary>
        private static void AnalyseArgs(string[] args)
        {
            // 解析参数信息
            List<string> argList = new List<string>();
            if (args != null && args.Length > 0)
            {
                foreach (string arg0 in args)
                {
                    string arg = arg0.Trim();
                    if (arg.StartsWith("PASS:")) Password = arg.Substring("PASS:".Length);
                    else argList.Add(arg);
                }
            }
            Args = argList.ToArray();
        }

    }

    public class Depends
    {
        /// <summary>
        /// 解压依赖dll,后重启应用
        /// </summary>
        public static void Export(string[] args)
        {
            if (args != null && args.Length > 0)
            {
                string ZipLib = curDir() + "ICSharpCode.SharpZipLib.dll";
                string Tool = curDir() + "Tools.dll";
                if (!File.Exists(ZipLib) || !File.Exists(Tool))
                {
                    if (!File.Exists(ZipLib)) SaveFile(Resources.ICSharpCode_SharpZipLib, ZipLib);
                    if (!File.Exists(Tool)) SaveFile(Resources.Tools, Tool);

                    //string Arg = ComBineArgs(args);
                    //System.Diagnostics.Process.Start(curExecutablePath(), Arg);
                    //System.Environment.Exit(0); //退出
                }
            }
        }

        /// <summary>
        /// 合并参数为单个串
        /// </summary>
        private static string ComBineArgs(string[] args)
        {
            string str = "";
            foreach (string arg0 in args)
            {
                string arg = arg0.Trim().Trim('"');
                str += " \"" + arg + "\"";
            }
            return str.Substring(1);
        }

        /// <summary>
        /// 获取当前运行路径
        /// </summary>
        public static string curDir()
        {
            return AppDomain.CurrentDomain.BaseDirectory;
        }

        /// <summary>
        /// 获取当前运行Exe的路径
        /// </summary>
        public static string curExecutablePath()
        {
            return System.Windows.Forms.Application.ExecutablePath;
        }

        /// <summary>
        /// 保存Byte数组为文件
        /// </summary>
        public static void SaveFile(Byte[] array, string path, bool repalce = false)
        {
            if (repalce && File.Exists(path)) File.Delete(path);    // 若目标文件存在,则替换
            if (!File.Exists(path))
            {
                // 创建输出路径
                String dir = Path.GetDirectoryName(path);

                // 创建输出流
                FileStream fs = new FileStream(path, FileMode.Create);

                //将byte数组写入文件中
                fs.Write(array, 0, array.Length);
                fs.Close();
            }
        }

        / <summary>
        / 删除文件
        / </summary>
        //public static void deletFile(string Name)
        //{
        //    string path = AppDomain.CurrentDomain.BaseDirectory + Name;
        //    if (File.Exists(path)) File.Delete(path);
        //}
    }

    public class AutoDelet
    {
        /// <summary>
        /// 删除文件
        /// </summary>
        public static void deletFiles(string[] Names)
        {
            try
            {
                //Set ws = CreateObject("Wscript.Shell") 
                //WScript.sleep 5000
                //ws.run "cmd /c ?> $",vbhide
                //ws.run "cmd /c del $",vbhide
                //ws.run "cmd /c ?> $.vbs",vbhide
                //ws.run "cmd /c del $.vbs",vbhide

                string vbsName = "Clear.vbs";
                StringBuilder Str = new StringBuilder();
                Str.AppendLine("Set ws = CreateObject(\"Wscript.Shell\")");
                Str.AppendLine("WScript.sleep 1000");
                Str.AppendLine("ws.run \"cmd /c del " + vbsName + "\",vbhide");

                string dir = AppDomain.CurrentDomain.BaseDirectory;
                foreach (string name in Names)
                {
                    if (File.Exists(dir + name)) Str.AppendLine("ws.run \"cmd /c del " + name + "\",vbhide");
                }
                string data = Str.ToString();

                SaveFile(data, dir + vbsName);
                System.Diagnostics.Process.Start(dir + vbsName);

                System.Environment.Exit(0); //退出
            }
            catch (Exception) { }
        }

        /// <summary>  
        /// 保存数据data到文件处理过程,返回值为保存的文件名  
        /// </summary>  
        private static String SaveFile(String data, String filePath)
        {
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false, Encoding.Default);     //文件已覆盖方式添加内容  

            file1.Write(data);                                                              //保存数据到文件  

            file1.Close();                                                                  //关闭文件  
            file1.Dispose();                                                                //释放对象  

            return filePath;
        }
    }

}





  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值