Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="outputdir"></param>
        /// <param name="ProgressCallback">由于无法直接获取整体解压缩后的流的大小,因此没有totoal值</param>
        public static void DirDecompression(string source, string outputdir, Action <ProgressArgs> ProgressCallback, Action Complete)
        {
            var sourcestream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.None);
            var gz           = new GZipStream(sourcestream, CompressionMode.Decompress);
            var count        = 0;
            var namelen      = 0;
            var buffer       = new byte[4096];

            byte[] namebyte;
            string name, upfolder;
            var    tag     = new byte[4];
            var    lenbyte = new byte[8];
            long   filelen = 0;

            while ((count = gz.Read(tag, 0, tag.Length)) > 0)
            {
                var memoryStream = new MemoryStream();
                namelen  = BitConverter.ToInt32(tag, 0);
                namebyte = new byte[namelen];
                gz.Read(namebyte, 0, namebyte.Length);
                name     = Encoding.Unicode.GetString(namebyte);
                upfolder = outputdir + name.Substring(0, name.LastIndexOf("\\")); //上级目录的全路径
                name     = outputdir + name;                                      //该文件的全路径
                gz.Read(lenbyte, 0, lenbyte.Length);
                filelen = BitConverter.ToInt64(lenbyte, 0);
                var p  = name.LastIndexOf("\\") + 1;
                var pa = new ProgressArgs {
                    Description = "正在解压缩",
                    Position    = 0,
                    PreFileName =
                        name.Substring(p, name.Length - p),
                    PreFileProgress = 0,
                    PreFileTotal    = filelen,
                    Total           = 0
                };
                memoryStream = new MemoryStream();
                var terms = (int)filelen / 4096;
                var tail  = (int)filelen % 4096;
                for (var i = 0; i < terms; ++i)
                {
                    gz.Read(buffer, 0, buffer.Length);
                    pa.PreFileProgress += buffer.Length;
                    ProgressCallback(pa);
                    memoryStream.Write(buffer, 0, buffer.Length);
                }
                gz.Read(buffer, 0, tail);
                pa.PreFileProgress += tail;
                ProgressCallback(pa);
                memoryStream.Write(buffer, 0, tail);
                memoryStream.Seek(0, SeekOrigin.Begin);
                if (!Directory.Exists(upfolder))
                {
                    Directory.CreateDirectory(upfolder);
                }
                var fs = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.None);
                memoryStream.CopyTo(fs);
                fs.Flush();
                fs.Close();
                memoryStream.Close();
                Complete();
            }
            gz.Close();
        }