压缩文件程.ZIP

压缩:

    /// <summary>
    /// 压缩文件
    /// </summary>
    public class ZipFile
    {
        public ZipFile()
        {
           
        }

        /// <summary>
        ///  获取文件压缩进度
        /// </summary>
        /// <param name="CurrentZipFileLength">当前文件压缩的流长</param>
        /// <param name="length">当前压缩文件的总长度</param>
        public delegate void GetZipFileProgress(int CurrentZipFileLength,long length);

        /// <summary>
        /// 获取文件压缩进度事件
        /// </summary>
        public event GetZipFileProgress GetZipFileProgressEvent;

        /// <summary>
        ///  获取文件夹压缩进度
        /// </summary>
        /// <param name="count">当前压缩有几个文件</param>
        /// <param name="counts">当前问价有几个文件</param>
        public delegate void GetZipFolderProgress(int count, int counts);

        /// <summary>
        /// 获取文件夹压缩进度事件
        /// </summary>
        public event GetZipFolderProgress GetZipFolderProgressEvent;

        /// <summary>
        /// 压缩单个文件
        /// </summary>
        /// <param name="FileToZip">需要压缩的源文件路径及名称</param>
        /// <param name="ZipedFile">压缩后的文件名</param>
        /// <param name="CompressionLevel">压缩等级(0-9)</param>
        /// <param name="BlockSize">每次压缩的大小</param>
        /// <returns></returns>
        public bool Zip(string FileToZip, string ZipedFile, int CompressionLevel, int BlockSize)
        {
            //如果文件没有找到,则报错
            System.Diagnostics.Debug.Assert(File.Exists(FileToZip), "该文件不存在");
            //if (!System.IO.File.Exists(FileToZip))
            //{
            //    //文件不存在
            //    //return;
            //   
            //    //throw new System.IO.FileNotFoundException("文件不存在 " + FileToZip + " could not be found. Zipping aborderd");
            //}
            bool result = true;
            //获取源文件名
            int index = FileToZip.LastIndexOf('\\')+1;

            //打开源文件并读取它
            FileStream StreamToZip = new FileStream(FileToZip, FileMode.Open, FileAccess.Read);
            //获取源文件长度
            long length = StreamToZip.Length;
            FileStream ZipFile = File.Create(ZipedFile);
            ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
          
            ZipEntry ZipEntry = new ZipEntry(FileToZip.Substring(index));
            ZipStream.PutNextEntry(ZipEntry);
            //压缩等级
            ZipStream.SetLevel(CompressionLevel);
            byte[] buffer = new byte[BlockSize];
            Int32 size = StreamToZip.Read(buffer, 0, buffer.Length);
            ZipStream.Write(buffer, 0, size);
            try
            {
                while (size < StreamToZip.Length)
                {
                    int sizeRead = StreamToZip.Read(buffer, 0, buffer.Length);
                    ZipStream.Write(buffer, 0, sizeRead);
                    size += sizeRead;
                    if(GetZipFileProgressEvent!=null)
                    {
                        GetZipFileProgressEvent(size, length);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Trace(ex);
                result = false;
            }
            finally
            {
                if (ZipStream!=null)
                {
                     ZipStream.Finish();
                     ZipStream.Close();
                }
                if (StreamToZip!=null)
                {
                   StreamToZip.Close();
                }
            }
            return result;
        }

        /// <summary>
        /// 压缩文件夹(直接压缩),返回是否成功
        /// </summary>
        /// <param name="sRootDir"></param>
        /// <param name="zipFileName"></param>
        /// <returns></returns>
        public bool ZipDir(string sRootDir, string zipFileName)
        {
            return ZipFileMain(new string[] { sRootDir, zipFileName });
        }

        /// <summary>
        /// 获取压缩文件夹中文件是否成功的信息
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private bool ZipFileMain(string[] args)
        {
            string[] filenames = Directory.GetFiles(args[0]);
            //获取文件夹有几个文件
            int counts = filenames.Length;
            int count = 0;
            Crc32 crc = new Crc32();
            ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
            bool result = true;
            try
            {
                s.SetLevel(6); // 0 - store only to 9 - means best compression

                foreach (string file in filenames)
                {
                    //打开压缩文件
                    FileStream fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    ZipEntry entry = new ZipEntry(file.Replace(args[0], ""));

                    entry.DateTime = DateTime.Now;

                    entry.Size = fs.Length;
                    fs.Close();

                    crc.Reset();
                    crc.Update(buffer);

                    entry.Crc = crc.Value;

                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                    count++;

                    if (GetZipFolderProgressEvent != null)
                    {
                        GetZipFolderProgressEvent(count, counts);
                    }

                }
                string[] dirs = Directory.GetDirectories(args[0]);
                foreach (string dir in dirs)
                {
                    //if (dir.IndexOf("tempdoc") > 0) continue;
                    ZipDir(args[0], dir, s, crc);
                }
            }
            catch (Exception ex)
            {
                Logger.Trace(ex);
                return false;
            }
            finally
            {
                if (s != null)
                {
                    s.Finish();
                    s.Close();
                }
            }
            return result;
        }

        /// <summary>
        /// 文件夹压缩
        /// </summary>
        /// <param name="sRootDir"></param>
        /// <param name="sDir"></param>
        /// <param name="s"></param>
        /// <param name="crc"></param>
        private void ZipDir(string sRootDir, string sDir, ZipOutputStream s, Crc32 crc)
        {
            string[] filenames = Directory.GetFiles(sDir);
            string[] dirs = Directory.GetDirectories(sDir);
            foreach (string file in filenames)
            {
                //打开压缩文件
                FileStream fs = File.OpenRead(file);
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                ZipEntry entry = new ZipEntry(file.Replace(sRootDir, ""));
                entry.DateTime = DateTime.Now;
                entry.Size = fs.Length;
                fs.Close();
                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;
                s.PutNextEntry(entry);
                s.Write(buffer, 0, buffer.Length);
            }
            foreach (string dir in dirs)
            {
                //if (dir.IndexOf("tempdoc") > 0) continue;
                ZipDir(sRootDir, dir, s, crc);
            }
        }

        /// <summary>
        /// 获取压缩文件夹中部分文件
        /// </summary>
        /// <param name="args"></param>
        /// <param name="files">文件夹中不需要压缩文件的名称</param>
        /// <returns></returns>
        public bool ZipFolderContainFile(string[] args,string[] files)
        {
            string[] filenames = Directory.GetFiles(args[0]);
            //获取文件夹有几个文件是要压缩的
            int counts = filenames.Length-files.Length;
            int count = 0;
            Crc32 crc = new Crc32();
            ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
            bool result = true;
            try
            {
                s.SetLevel(6); // 0 - store only to 9 - means best compression

                foreach (string file in filenames)
                {
                    foreach(string filename in files)
                    {
                        if(file==filename)
                        {
                            break;
                        }
                        //打开压缩文件
                        FileStream fs = File.OpenRead(file);

                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        ZipEntry entry = new ZipEntry(file.Replace(args[0], ""));

                        entry.DateTime = DateTime.Now;

                        entry.Size = fs.Length;
                        fs.Close();

                        crc.Reset();
                        crc.Update(buffer);

                        entry.Crc = crc.Value;

                        s.PutNextEntry(entry);

                        s.Write(buffer, 0, buffer.Length);
                        count++;

                        if (GetZipFolderProgressEvent != null)
                        {
                            GetZipFolderProgressEvent(count, counts);
                        }

                    }
                  
                }
                string[] dirs = Directory.GetDirectories(args[0]);
                foreach (string dir in dirs)
                {
                    //if (dir.IndexOf("tempdoc") > 0) continue;
                    ZipDir(args[0], dir, s, crc);
                }
            }
            catch (Exception ex)
            {
                Logger.Trace(ex);
                result = false;
            }
            finally
            {
                if (s != null)
                {
                    s.Finish();
                    s.Close();
                }
            }
            return result;
        }

        /// <summary>
        /// 压缩文件列表
        /// </summary>
        /// <param name="fileNameList">要压缩的文件列表</param>
        /// <param name="zipFileName">压缩后的生成文件</param>
        /// <returns>true表示压缩成功,false表示压缩失败</returns>
        public bool ZipFiles(List<string> fileNameList,string zipFileName)
        {
            string[] filenames = fileNameList.ToArray();
            //获取文件夹有几个文件
            int counts = filenames.Length;
            int count = 0;
            Crc32 crc = new Crc32();
            ZipOutputStream s = new ZipOutputStream(File.Create(zipFileName));
            bool result = true;
            try
            {
                s.SetLevel(6); // 0 - store only to 9 - means best compression

                foreach (string file in filenames)
                {
                    //打开压缩文件
                    FileStream fs = File.OpenRead(file);
                    long pai = 1024 * 1024 * 1;//每1兆写一次
                    long forint = fs.Length / pai + 1;
                    byte[] buffer = null;
                    string replacePath = Path.GetDirectoryName(file);
                    string filename = file.Replace(replacePath + "\\", "");//只是获取文件名,但是没有目录
                    ZipEntry entry = new ZipEntry(filename);
                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    s.PutNextEntry(entry);

                    //分段压缩
                    for (long i = 1; i <= forint; i++)
                    {
                        if (pai * i < fs.Length)
                        {
                            buffer = new byte[pai];
                            fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                        }
                        else
                        {
                            if (fs.Length < pai)
                            {
                                buffer = new byte[fs.Length];
                            }
                            else
                            {
                                buffer = new byte[fs.Length - pai * (i - 1)];
                                fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                            }
                        }
                        fs.Read(buffer, 0, buffer.Length);
                        crc.Reset();
                        crc.Update(buffer);
                        s.Write(buffer, 0, buffer.Length);
                        s.Flush();
                    }

                    fs.Close();

                    count++;
                    if (GetZipFolderProgressEvent != null)
                    {
                        GetZipFolderProgressEvent(count, counts);
                    }
                }              
            }
            catch (Exception ex)
            {
                Logger.Trace(ex);
                result= false;
            }
            finally
            {
                if (s != null)
                {
                    s.Finish();
                    s.Close();
                }
            }
            return result;           
        }

        /// <summary>
        /// 压缩多层目录(压缩文件夹采用分阶段压缩) 
        /// </summary> 
        /// <param name="strDirectory">要压缩的目录</param> 
        /// <param name="zipedFile">压缩后的生成文件</param>
        /// <returns>true表示压缩成功,false表示压缩失败</returns>
        public static bool ZipFileDirectory(string strDirectory, string zipedFile)
        {
            //要压缩的目录不存在
            if (!Directory.Exists(strDirectory))
            {
                return false;
            }
            bool zipIsSuccess;
            using (FileStream zipFile = System.IO.File.Create(zipedFile))
            {
                using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
                {
                    zipIsSuccess = ZipSetp(strDirectory, zipOutputStream, "", zipedFile);
                }
            }
            return zipIsSuccess;
        }

        /// <summary>
        /// 压缩多层目录(压缩文件夹采用分阶段压缩) 
        /// </summary> 
        /// <param name="strDirectory">要压缩的目录</param> 
        /// <param name="zipedFile">压缩后的生成文件</param>
        /// <returns>true表示压缩成功,false表示压缩失败</returns>
        public static bool ZipFileDirectory(string strDirectory, string zipedFile, List<string> withoutDirectorys)
        {
            //要压缩的目录不存在
            if (!Directory.Exists(strDirectory))
            {
                return false;
            }
            bool zipIsSuccess;
            using (FileStream zipFile = System.IO.File.Create(zipedFile))
            {
                using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
                {
                    zipIsSuccess = ZipSetp(strDirectory, zipOutputStream, "", withoutDirectorys, zipedFile);
                }
            }
            return zipIsSuccess;
        }


        /// <summary> 
        /// 递归遍历目录 
        /// </summary> 
        /// <param name="strDirectory">要压缩的目录</param> 
        /// <param name="zipOutputStream">压缩后的生成文件流</param> 
        /// <param name="parentPath">当前父目录</param>
        /// <returns>true表示压缩成功,false表示压缩失败</returns>
        private static bool ZipSetp(string strDirectory, ZipOutputStream zipOutputStream, string parentPath, string targetZipPath)
        {
            if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
            {
                strDirectory += Path.DirectorySeparatorChar;
            }

            try
            {
                Crc32 crc = new Crc32();
                string[] filenames = Directory.GetFileSystemEntries(strDirectory);
                foreach (string file in filenames)// 遍历所有的文件和目录
                {
                    if (Directory.Exists(file))// 当是目录时,就递归该目录下面的文件
                    {
                        string pPath = parentPath;
                        pPath += file.Substring(file.LastIndexOf("\\") + 1);
                        pPath += "\\";
                        ZipSetp(file, zipOutputStream, pPath, targetZipPath);
                    }
                    else // 否则直接压缩文件
                    {
                        if (file != targetZipPath)
                        {
                            using (FileStream fs = File.OpenRead(file))
                            {
                                //分段压缩,主要解决单个文件太大
                                long pai = 1024 * 1024 * 1;//每1兆写一次
                                long forint = fs.Length / pai + 1;
                                byte[] buffer = null;
                                string filename = parentPath + file.Substring(file.LastIndexOf("\\") + 1);//获取文件名,但有目录
                                ZipEntry entry = new ZipEntry(filename);
                                entry.DateTime = DateTime.Now;
                                entry.Size = fs.Length;
                                zipOutputStream.PutNextEntry(entry);
                                for (long i = 1; i <= forint; i++)
                                {
                                    if (pai * i < fs.Length)
                                    {
                                        buffer = new byte[pai];
                                        fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                                    }
                                    else
                                    {
                                        if (fs.Length < pai)
                                        {
                                            buffer = new byte[fs.Length];
                                        }
                                        else
                                        {
                                            buffer = new byte[fs.Length - pai * (i - 1)];
                                            fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                                        }
                                    }
                                    fs.Read(buffer, 0, buffer.Length);
                                    crc.Reset();
                                    crc.Update(buffer);
                                    zipOutputStream.Write(buffer, 0, buffer.Length);
                                    zipOutputStream.Flush();
                                }
                                //直接压缩
                                //byte[] buffer = new byte[fs.Length];
                                //fs.Read(buffer, 0, buffer.Length);
                                //string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
                                //ZipEntry entry = new ZipEntry(fileName);
                                //entry.DateTime = DateTime.Now;
                                //entry.Size = fs.Length;
                                //fs.Close();
                                //crc.Reset();
                                //crc.Update(buffer);
                                //entry.Crc = crc.Value;
                                //zipOutputStream.PutNextEntry(entry);
                                //zipOutputStream.Write(buffer, 0, buffer.Length);
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                zipOutputStream.Flush();
                zipOutputStream.Close();
                return false;
            }
            return true;
        }

        /// <summary> 
        /// 递归遍历目录 
        /// </summary> 
        /// <param name="strDirectory">要压缩的目录</param> 
        /// <param name="zipOutputStream">压缩后的生成文件流</param> 
        /// <param name="parentPath">当前父目录</param>
        /// <returns>true表示压缩成功,false表示压缩失败</returns>
        private static bool ZipSetp(string strDirectory, ZipOutputStream zipOutputStream, string parentPath, List<string> withoutDirectorys, string targetZipPath)
        {
            if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
            {
                strDirectory += Path.DirectorySeparatorChar;
            }

            try
            {
                Crc32 crc = new Crc32();
                string[] filenames = Directory.GetFileSystemEntries(strDirectory);
                foreach (string file in filenames)// 遍历所有的文件和目录
                {
                    if (Directory.Exists(file))// 当是目录时,就递归该目录下面的文件
                    {
                        if (withoutDirectorys.Contains(file))
                            continue;
                        string pPath = parentPath;
                        pPath += file.Substring(file.LastIndexOf("\\") + 1);
                        pPath += "\\";
                        ZipSetp(file, zipOutputStream, pPath, targetZipPath);
                    }
                    else // 否则直接压缩文件
                    {
                        using (FileStream fs = File.OpenRead(file))
                        {
                            //分段压缩,主要解决单个文件太大
                            long pai = 1024 * 1024 * 1;//每1兆写一次
                            long forint = fs.Length / pai + 1;
                            byte[] buffer = null;
                            string filename = parentPath + file.Substring(file.LastIndexOf("\\") + 1);//获取文件名,但有目录
                            ZipEntry entry = new ZipEntry(filename);
                            entry.DateTime = DateTime.Now;
                            entry.Size = fs.Length;
                            zipOutputStream.PutNextEntry(entry);
                            for (long i = 1; i <= forint; i++)
                            {
                                if (pai * i < fs.Length)
                                {
                                    buffer = new byte[pai];
                                    fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                                }
                                else
                                {
                                    if (fs.Length < pai)
                                    {
                                        buffer = new byte[fs.Length];
                                    }
                                    else
                                    {
                                        buffer = new byte[fs.Length - pai * (i - 1)];
                                        fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
                                    }
                                }
                                fs.Read(buffer, 0, buffer.Length);
                                crc.Reset();
                                crc.Update(buffer);
                                zipOutputStream.Write(buffer, 0, buffer.Length);
                                zipOutputStream.Flush();
                            }
                            //直接压缩
                            //byte[] buffer = new byte[fs.Length];
                            //fs.Read(buffer, 0, buffer.Length);
                            //string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
                            //ZipEntry entry = new ZipEntry(fileName);
                            //entry.DateTime = DateTime.Now;
                            //entry.Size = fs.Length;
                            //fs.Close();
                            //crc.Reset();
                            //crc.Update(buffer);
                            //entry.Crc = crc.Value;
                            //zipOutputStream.PutNextEntry(entry);
                            //zipOutputStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                return false;
            }
            return true;
        } 

        /// <summary>
        /// 更新 Zip 包中的文件
        /// </summary>
        /// <param name="srcZipFileName">Zip 包的全名</param>
        /// <param name="srcFileName">要添加到包中的文件名</param>
        /// <param name="destPath">文件在Zip包中的相对位置</param>
        public void UpdateZipFile(String srcZipFileName, String srcFileName, String destPath)
        {
            string[] unZipFileInfos = new string[2];
            unZipFileInfos[0] = srcZipFileName;
            //获取临时解压目录
            string tempDirectory = Path.GetDirectoryName(srcZipFileName) + Path.DirectorySeparatorChar + System.Guid.NewGuid().ToString().Replace("-", "") + Path.DirectorySeparatorChar;
            //要更新的文件在临时文件夹中位置
            string destFilePath=tempDirectory+destPath;
            unZipFileInfos[1] = tempDirectory;
            //如果临时文件夹目录不存在则创建
            if (!System.IO.Directory.Exists(tempDirectory))
            {
                System.IO.Directory.CreateDirectory(tempDirectory);
            }
            CommonLibrary.UnZipFile unZipFile = new UnZipFile();
            //解压文件到临时文件夹
            unZipFile.UnZip(unZipFileInfos);
            //更新需要更新的文件
            System.IO.File.Copy(srcFileName,destFilePath, true);
            //更新完成后重新压缩文件到临时文件夹
            ZipFileDirectory(tempDirectory, tempDirectory + Path.GetFileName(srcZipFileName));
            //更新zip文件
            System.IO.File.Copy(tempDirectory + Path.GetFileName(srcZipFileName), srcZipFileName, true);
            //删除临时文件夹
            System.IO.Directory.Delete(tempDirectory, true);
            //ICSharpCode.SharpZipLib.Zip.ZipFile zipFileEntry = new ICSharpCode.SharpZipLib.Zip.ZipFile(srcZipFileName);
            //// Must call BeginUpdate to start, and CommitUpdate at the end.
            //zipFileEntry.BeginUpdate();
        
            ////添加文件到 Zip 包中
            //IStaticDataSource fileEntry = new FileEntry(srcFileName);
            //zipFileEntry.Add(fileEntry, destPath);
            //// Both CommitUpdate and Close must be called.
            //zipFileEntry.CommitUpdate();
            //((FileEntry)fileEntry).FileStream.Close();
            //zipFileEntry.Close();
        }//end method
    }//end class

    public class FileEntry : IStaticDataSource
    {
         private   FileStream fileStream;

        public FileEntry(String filename)
        {
            fileStream = File.OpenRead(filename);
           // fileStream.Close();
        }
        public Stream GetSource()
        {
            return fileStream;
        }
        /// <summary>
        /// 对象流
        /// </summary>
        public FileStream FileStream
        {
            get { return fileStream; }
        }

    }//end class

posted @ 2012-06-21 13:39  二哥(阿伟)  阅读(227)  评论(0编辑  收藏  举报