实时显示当前正在解压缩的文件名

最近需要一个解压缩的需求,因为文件较多,所以希望能看到正在解压的文件名,于是需要个委托来返回文件名。
首先我们先定义一个解压缩的帮助类,这里我用了DotNetZip.dll。

using Ionic.Zlib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XXX
{	
	public class GZipHelper
    {
        public delegate void ProgressDelegate(string sMessage);
        public static byte[] Compress(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            MemoryStream stream = new MemoryStream();
            using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression))
            {
                gZipStream.Write(data, 0, data.Length);
                gZipStream.Close();
            }

            return stream.ToArray();
        }

        public static byte[] Decompress(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            MemoryStream stream = new MemoryStream(data);
            MemoryStream decompress_stream = new MemoryStream(1024 * 5);
            using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress, true))
            {
                int count = 0;
                
                do
                {
                    byte[] byteBuffer = new byte[512];
                    count = gZipStream.Read(byteBuffer, 0, byteBuffer.Length);
                    decompress_stream.Write(byteBuffer, 0, count);
                } while (count > 0);

                return decompress_stream.ToArray();
            }
        }

        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="sourceFile">源文件</param>
        /// <param name="destinationFile">目标文件</param>
        public static void CompressFile(string sourceFile, string destinationFile)
        {
            if (!File.Exists(sourceFile)) //判断文件是否存在
                throw new FileNotFoundException();
            //if (!File.Exists(destinationFile)) //判断目标文件文件是否存在
            //    File.Delete(destinationFile);
            //创建文件流和字节数组
            byte[] buffer = null;
            FileStream sourceStream = null;
            FileStream destinationStream = null;
            GZipStream compressedStream = null;
            try
            {
                sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                buffer = new byte[sourceStream.Length];
                //把文件流存放到字节数组中
                int checkCounter = sourceStream.Read(buffer, 0, buffer.Length);
                if (checkCounter != buffer.Length)
                {
                    throw new ApplicationException();
                }
                destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);
                //创建GzipStream实例,写入压缩的文件流
                compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true);
                compressedStream.Write(buffer, 0, buffer.Length);
            }
            finally
            {
                // Make sure we allways close all streams
                if (sourceStream != null)
                { sourceStream.Close(); }
                if (compressedStream != null)
                { compressedStream.Close(); }
                if (destinationStream != null)
                { destinationStream.Close(); }
            }
        }

        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="sourceFile">源文件</param>
        /// <param name="destinationFile">目标文件</param>
        public static void DecompressFile(string sourceFile, string destinationFile)
        {
            if (!File.Exists(sourceFile))
            {
                throw new FileNotFoundException();
            }
            FileStream stream = null;
            FileStream stream2 = null;
            GZipStream stream3 = null;
            byte[] buffer = null;
            try
            {
                stream = new FileStream(sourceFile, FileMode.Open);
                stream3 = new GZipStream(stream, CompressionMode.Decompress, true);
                buffer = new byte[4];
                int num = ((int)stream.Length) - 4;
                stream.Position = num;
                stream.Read(buffer, 0, 4);
                stream.Position = 0L;
                byte[] buffer2 = new byte[BitConverter.ToInt32(buffer, 0) + 100];
                int offset = 0;
                int count = 0;
                while (true)
                {
                    int num5 = stream3.Read(buffer2, offset, 100);
                    if (num5 == 0)
                    {
                        break;
                    }
                    offset += num5;
                    count += num5;
                }
                stream2 = new FileStream(destinationFile, FileMode.Create);
                stream2.Write(buffer2, 0, count);
                stream2.Flush();
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
                if (stream3 != null)
                {
                    stream3.Close();
                }
                if (stream2 != null)
                {
                    stream2.Close();
                }
            }
        }
        
        private static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
        {
            //Compress file name
            char[] chars = sRelativePath.ToCharArray();
            zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
            foreach (char c in chars)
                zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));

            //Compress file content
            byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
            zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
            zipStream.Write(bytes, 0, bytes.Length);
        }

        private static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress)
        {
            //Decompress file name
            byte[] bytes = new byte[sizeof(int)];
            int Readed = zipStream.Read(bytes, 0, sizeof(int));
            if (Readed < sizeof(int))
                return false;

            int iNameLen = BitConverter.ToInt32(bytes, 0);
            bytes = new byte[sizeof(char)];
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < iNameLen; i++)
            {
                zipStream.Read(bytes, 0, sizeof(char));
                char c = BitConverter.ToChar(bytes, 0);
                sb.Append(c);
            }
            string sFileName = sb.ToString();
            if (progress != null)
                progress(sFileName);
            //Decompress file content
            bytes = new byte[sizeof(int)];
            zipStream.Read(bytes, 0, sizeof(int));
            int iFileLen = BitConverter.ToInt32(bytes, 0);

            bytes = new byte[iFileLen];
            zipStream.Read(bytes, 0, bytes.Length);

            string sFilePath = Path.Combine(sDir, sFileName);
            string sFinalDir = Path.GetDirectoryName(sFilePath);
            if (!Directory.Exists(sFinalDir))
                Directory.CreateDirectory(sFinalDir);

            using (FileStream outFile = new FileStream(sFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                outFile.Write(bytes, 0, iFileLen);

            return true;
        }
        /// <summary>
        /// 压缩文件夹
        /// </summary>
        /// <param name="sInDir">源文件夹</param>
        /// <param name="sOutFile">目标文件</param>
        public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
        {
            string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
            int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;

            using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
            using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
                foreach (string sFilePath in sFiles)
                {
                    string sRelativePath = sFilePath.Substring(iDirLen);
                    if (progress != null)
                        progress(sRelativePath);
                    CompressFile(sInDir, sRelativePath, str);
                }
        }
        /// <summary>
        /// 解压文件夹
        /// </summary>
        /// <param name="sCompressedFile">源文件</param>
        /// <param name="sDir">目标文件夹</param>
        public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
        {
            using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None))
            using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
                while (DecompressFile(sDir, zipStream, progress)) ;
        }
    }
}

导入

//解压版
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
	ImportWindow import = new ImportWindow();
	DateTime dt = DateTime.Now;
	import.Show();
	EcgProject prjObj = null;
	await TaskAsyncHelper.RunAsync(new Action(() =>
	{
	    string userWorkFolderPath =“目标文件地址”;
	    GZipHelper.DecompressToDirectory(ofd.FileName, userWorkFolderPath, (filename) =>
	    {
	        Application.Current.Dispatcher.BeginInvoke(new Action(() => { import.LabelContent = string.Format("正在导入{0}", filename); }));
	    });
	}), new Action(() =>
	{
	    import.Close();
	    MessageBox.Show($"导入项目成功!{DateTime.Now - dt}");
	}));
}

导出

//压缩版
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == true)
{
	DateTime dt = DateTime.Now;
	ExportWindow import = new ExportWindow();
	import.Show();
	await TaskAsyncHelper.RunAsync(new Action(() => {
	    GZipHelper.CompressDirectory(“源文件位置”, sfd.FileName, (filename) => {
	        Application.Current.Dispatcher.BeginInvoke(new Action(() => { import.LabelContent = string.Format("正在导出{0}", filename); }));
	    });
	}), new Action(() =>
	{
	    import.Close();
	    MessageBoxHelper.ShowMessage($"Export OK!{DateTime.Now - dt}", $"导出项目成功!{DateTime.Now - dt}", (LangType)SysInfoModel.SysInfo.LangType);
	}));
}

自定义的ExportWindow与ImportWindow就不给出了。TaskAsyncHelper.RunAsync的方法如下

public static class TaskAsyncHelper
{
    /// <summary>  
    /// 将一个方法function异步运行,在执行完毕时执行回调callback  
    /// </summary>  
    /// <param name="function">异步方法,该方法没有参数,返回类型必须是void</param>  
    /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法没有参数,返回类型必须是void</param>  
    public static async Task RunAsync(Action function, Action callback)
    {
        Func<Task> taskFunc = () =>
        {
            return Task.Run(function);
        };
        await taskFunc();
        if (callback != null)
            callback();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值