C#通过7Z解压和压缩文件

前言

在网络情况不够良好或者网速受限情况下,传输文件时,一般考虑使用压缩算法对文件进行压缩。7z压缩是一个压缩率比较高的软件,我们可以通过他来处理我们的文件。主要有两种方式进行压缩:方式1,直接通过调用库方式,可以在网上找到他的库算法;方式2,通过CMD命令行模式调用。

1、直接调用库

直接调用库,有一个好处是后期可控制性比较好,它还提供了一个处理回调函数。可以查看处理情况。但传递参数较多,需要好好研究研究。

        //文件压缩处理
        private void ProcessFileEncode(string inputName, string outputName)
        {
            Stream inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);

            FileStream outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);

            FileStream trainStream = null;
            Int32 dictionary = 1 << 23;

            Int32 posStateBits = 2;
            Int32 litContextBits = 3;
            Int32 litPosBits = 0;
            Int32 algorithm = 2;
            Int32 numFastBytes = 128;

            bool eos = true;

            CoderPropID[] propIDs =
            {
                    CoderPropID.DictionarySize,
                    CoderPropID.PosStateBits,
                    CoderPropID.LitContextBits,
                    CoderPropID.LitPosBits,
                    CoderPropID.Algorithm,
                    CoderPropID.NumFastBytes,
                    CoderPropID.MatchFinder,
                    CoderPropID.EndMarker
                };
            object[] properties =
            {
                    dictionary,
                    posStateBits,
                    litContextBits,
                    litPosBits,
                    algorithm,
                    numFastBytes,
                    "bt4",
                    eos
                };

            Encoder encoder = new Encoder();
            encoder.SetCoderProperties(propIDs, properties);
            encoder.WriteCoderProperties(outStream);
            Int64 fileSize = inStream.Length;
            for (int i = 0; i < 8; i++)
                outStream.WriteByte((Byte)(fileSize >> (8 * i)));
            if (trainStream != null)
            {
                CDoubleStream doubleStream = new CDoubleStream();
                doubleStream.s1 = trainStream;
                doubleStream.s2 = inStream;
                doubleStream.fileIndex = 0;
                inStream = doubleStream;
                long trainFileSize = trainStream.Length;
                doubleStream.skipSize = 0;
                if (trainFileSize > dictionary)
                    doubleStream.skipSize = trainFileSize - dictionary;
                trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
                encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
            }
            encoder.Code(inStream, outStream, -1, -1, proceCallInfo);
            outStream.Close();
            inStream.Close();
        }

        //文件解压处理
        private void ProcessFileDecode(string inputName, string outputName)
        {
            Stream inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);

            FileStream outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);

            byte[] properties = new byte[5];
            if (inStream.Read(properties, 0, 5) != 5)
                throw new Exception("input .lzma is too short");
            Decoder decoder = new Decoder();
            decoder.SetDecoderProperties(properties);

            long outSize = 0;
            for (int i = 0; i < 8; i++)
            {
                int v = inStream.ReadByte();
                if (v < 0)
                    throw new Exception("Can't Read 1");
                outSize |= ((long)(byte)v) << (8 * i);
            }
            long compressedSize = inStream.Length - inStream.Position;
            decoder.Code(inStream, outStream, compressedSize, outSize, proceCallInfo);
            outStream.Close();
            inStream.Close();
        }

处理信息


        public class ProceCallInfo : BindableBase, ICodeProgress
        {
            private long inSize;

            public long InSize
            {
                get { return inSize; }
                set { Set(ref inSize, value); }
            }

            private long outSize;

            public long OutSize
            {
                get { return outSize; }
                set { Set(ref outSize, value); OnPropertyChanged("Ration"); }
            }

            private string processRatio;

            public string ProcessRatio
            {
                get { return processRatio; }
                set { Set(ref processRatio, value); }
            }

            public double Ration
            {
                get
                {
                    if (outSize == 0 || InSize == 0)
                        return 0;
                    else
                        return outSize * 1.0 / InSize;
                }
            }

            public void SetProgress(long inSize, long outSize)
            {
                InSize = inSize;
                OutSize = outSize;
            }
        }

2、CMD间接方式

        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="strInFilePath">指定需要压缩的文件,如C:\test\demo.xlsx,将压缩demo.xlsx文件</param>
        /// <param name="strOutFilePath">压缩后压缩文件的存放目录</param>
        public void CompressFile(string strInFilePath, string strOutFilePath)
        {
            Process process = new Process();
            process.StartInfo.FileName = this._7zInstallPath;
            process.StartInfo.Arguments = " a -t7z " + strOutFilePath + " " + strInFilePath + "";
            //隐藏DOS窗口
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.Start();
            process.WaitForExit();
            process.Close();
        }

        /// <summary>
        /// 解压缩
        /// </summary>
        /// <param name="strInFilePath">压缩文件的路径</param>
        /// <param name="strOutDirectoryPath">解压缩后文件的路径</param>
        public void DecompressFileToDestDirectory(string strInFilePath, string strOutDirectoryPath)
        {
            Process process = new Process();
            process.StartInfo.FileName = this._7zInstallPath;
            process.StartInfo.Arguments = " x " + strInFilePath + " -o" + strOutDirectoryPath + " -r ";
            //隐藏DOS窗口
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.Start();
            process.WaitForExit();
            process.Close();
        }

3、主调逻辑

压缩文件

        //压缩文件
        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string OrgfilePath = @"D:\图像\123.tiff";
            string outfilePath = @"D:\图像\777.7z";
            WriteInfo("start Process!");
            Button btn = sender as Button;
            btn.IsEnabled = false;
            stopwatch.Restart();
            string path = @"C:\Program Files\7-Zip\7zg.exe";
            ZipHelper zipHelper = new ZipHelper(path);
            await Task.Run(() =>
            {
                // zipHelper.CompressFile(OrgfilePath,outfilePath);
                ProcessFileEncode(OrgfilePath, outfilePath);
            });
            stopwatch.Stop();
            WriteInfo($"End Process {stopwatch.ElapsedMilliseconds}ms!");
            btn.IsEnabled = true;
        }

解压文件

  private async void Button_Click_2(object sender, RoutedEventArgs e)
        {
            string OrgfilePath = @"D:\图像\777.7z";
            string outfilePath = @"D:\图像\777.tiff";
            WriteInfo("start Process!");
            Button btn = sender as Button;
            btn.IsEnabled = false;
            stopwatch.Restart();

            await Task.Run(() =>
            {
                // zipHelper.CompressDirectory(OrgfilePath, outfilePath);
                ProcessFileDecode(OrgfilePath, outfilePath);
            });

            stopwatch.Stop();
            WriteInfo($"End Process {stopwatch.ElapsedMilliseconds}ms!");
            btn.IsEnabled = true;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值