/// <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(); }