ASP.NET实现紧缩多个文件为.zip文件,实现批量下载功能

作者:袖梨 2022-06-25

址   http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

下面是对#ZipLib进行.net下的解紧缩的办法的介绍。 


  1.BZip2    
     参加ICSharpCode.SharpZipLib.dll的引用,在#Develop的安装目次下的SharpDevelopbin目次下。然后在法度中应用using语句把BZip2 
   
  类库包含进来。    
  紧缩:应用BZip2的静态办法Compress。    
          它的第一个参数是所要紧缩的文件所代表的输入流,可以应用System.IO.File的静态办法OpenRead。   
          第二个参数是要建树的紧缩文件所代表的输出流,可以应用System.IO.File的静态办法Create创建,紧缩文件名是所要紧缩文件的文件名 
   
  加上紧缩后缀.bz(同样你也可以取其他的文件名)。    
          第三个参数是要紧缩的块大小(一般为2048的整数)。    
   
  解压:应用BZip2的静态办法Decompress。    
          它的第一个参数是所要解压的紧缩文件所代表的输入流,可以应用System.IO.File的静态办法OpenRead。   
          第二个参数是要建树的解压文件所代表的输出流,可以应用System.IO.File的静态办法Create创建,因为解压文件的文件名是去掉了紧缩 
   
  文件扩大名的紧缩文件名(你也可以做成解压文件与紧缩文件不合名的)。    
  编译你的法度,然后在号令行体式格式下输入bzip2   文件名(假设建树的C#文件是bzip2,就可以生成紧缩文件;输入bzip2   -d   文件名,就会解压 
  出文件来(-d是用来默示解压,你也可以应用其他的符号)。    
  呵呵,本来做紧缩可以这么简单的,紧缩结果也可以啊。 

 

 代码如下 复制代码
 using   System;    
  using   System.IO;    
  using   ICSharpCode.SharpZipLib.BZip2;    
   
  class   MainClass    
  {    
        public   static   void   Main(string[]   args)    
        {    
              if   (args[0]   ==   "-d")   {   //   解压    
                    BZip2.Decompress(File.OpenRead(args[1]),   File.Create(Path.GetFileNameWithoutExtension(args[1])));    
              }   else   {   //紧缩    
                    BZip2.Compress(File.OpenRead(args[0]),   File.Create(args[0]   +   ".bz"),   4096);    
              }    
        }    
  }    

2.GZip      
        参加ICSharpCode.SharpZipLib.dll的引用,在#Develop的安装目次下的SharpDevelopbin目次下。然后在法度中应用using语句把GZip类 
   
  库包含进来。      
        因为GZip没有BZip2的简单解紧缩办法,是以只能应用流办法来进行解紧缩。具体的办法见法度的申明。   
        编译法度,然后在号令行体式格式下输入GZip   文件名(假设建树的C#文件是GZip,就可以生成紧缩文件;输入GZip   -d   文件名,就会解压出文 
   
  件来(-d是用来默示解压,你也可以应用其他的符号)。      

 代码如下 复制代码
 using   System;    
  using   System.IO;    
   
  using   ICSharpCode.SharpZipLib.GZip;    
   
  class   MainClass    
  {    
        public   static   void   Main(string[]   args)    
        {    
              if   (args[0]   ==   "-d")   {   //   解压    
                    Stream   s   =   new   GZipInputStream(File.OpenRead(args[1]));    
                    //生成一个GZipInputStream流,用来打开紧缩文件。    
                  //因为GZipInputStream由Stream派生,所以它可以赋给Stream。    
                      //它的机关函数的参数是一个默示要解压的紧缩文件所代表的文件流    
                    FileStream   fs   =   File.Create(Path.GetFileNameWithoutExtension(args[1]));    
                    //生成一个文件流,它用来生成解压文件    
                    //可以应用System.IO.File的静态函数Create来生成文件流    
                    int   size   =   2048;//指定紧缩块的大小,一般为2048的倍数    
                    byte[]   writeData   =   new   byte[size];//指定缓冲区的大小    
                    while   (true)   {    
                          size   =   s.Read(writeData,   0,   size);//读入一个紧缩块    
                          if   (size   >   0)   {    
                                fs.Write(writeData,   0,   size);//写入解压文件代表的文件流    
                          }   else   {    
                                break;//若读到紧缩文件尾,则停止    
                          }    
                    }    
                    s.Close();    
              }   else   {   //   紧缩    
                    Stream   s   =   new   GZipOutputStream(File.Create(args[0]   +   ".gz"));    
                    //生成一个GZipOutputStream流,用来生成紧缩文件。    
                                                  //因为GZipOutputStream由Stream派生,所以它可以赋给Stream。    
                      FileStream   fs   =   File.OpenRead(args[0]);    
                    /生成一个文件流,它用来打开要紧缩的文件    
                    //可以应用System.IO.File的静态函数OpenRead来生成文件流    
                    byte[]   writeData   =   new   byte[fs.Length];    
                    //指定缓冲区的大小    
                    fs.Read(writeData,   0,   (int)fs.Length);    
                    //读入文件    
                    s.Write(writeData,   0,   writeData.Length);    
                    //写入紧缩文件    
                    s.Close();    
                    //封闭文件    
              }    
        }    
  }
  

应用这个类库固然好,然则也有些缺点,它只能紧缩文件夹第一级子目次中的“文件”(不包含文件夹和子目次)的景象,这也不克不及满足我的请求,我想要的是可以紧缩随便率性路径的多个文件。
      没办法,只好再想此外办法。愁闷了好久之后在别人的一篇文章中终于找到了灵感,别人的一篇文章是写在java中实现紧缩zip文件,我看了后发明在java中实现紧缩为zip文件很轻易。灵机一动我想到了.net中的J#,J#中应当有java中的如许类,若是有的话,那么我在我的C#法度中就可以引用了(哄骗.net特有的说话互操纵性)。于是我就上彀搜这方面的内容,终于在MSDN中找到了如许的例子

(http://msdn.microsoft.com/en-gb/library/aa686114(zh-cn).aspx#EHAA得来全不费工夫啊),贴出来找到的代码,大师共同窗习。

 代码如下 复制代码

using System;
using System.Collections;
using java.util;
using java.util.zip;

namespace CsZip
{
    public delegate Enumeration EnumerationMethod();

    ///


    /// Wraps java enumerators
    ///

    public class EnumerationAdapter : IEnumerable
    {
        private class EnumerationWrapper : IEnumerator
        {
            private EnumerationMethod m_Method;
            private Enumeration m_Wrapped;
            private object m_Current;

            public EnumerationWrapper(EnumerationMethod method)
            {
                m_Method = method;
            }

            // IEnumerator
            public object Current
            {
                get { return m_Current; }
            }

            public void Reset()
            {
                m_Wrapped = m_Method();
                if (m_Wrapped == null)
                    throw new InvalidOperationException();
            }

            public bool MoveNext()
            {
                if (m_Wrapped == null)
                    Reset();
                bool Result = m_Wrapped.hasMoreElements();
                if (Result)
                    m_Current = m_Wrapped.nextElement();
                return Result;
            }
        }

        private EnumerationMethod m_Method;

        public EnumerationAdapter(EnumerationMethod method)
        {
            if (method == null)
                throw new ArgumentException();
            m_Method = method;
        }

        // IEnumerable
        public IEnumerator GetEnumerator()
        {
            return new EnumerationWrapper(m_Method);
        }
    }

    public delegate bool FilterEntryMethod(ZipEntry e);

    ///


    /// Zip stream utils
    ///

    public class ZipUtility
    {
        public static void CopyStream(java.io.InputStream , java.io.OutputStream to)
        {
            sbyte[] buffer = new sbyte[8192];
            int got;
            while ((got = .read(buffer, 0, buffer.Length)) > 0)
                to.write(buffer, 0, got);
        }

        public static void ExtractZipFile(ZipFile file, string path, FilterEntryMethod filter)
        {
            foreach (ZipEntry entry in new EnumerationAdapter(new EnumerationMethod(file.entries)))
            {
                if (!entry.isDirectory())
                {
                    if ((filter == null || filter(entry)))
                    {
                        java.io.InputStream s = file.getInputStream(entry);
                        try
                        {
                            string fname = System.IO.Path.GetFileName(entry.getName());
                            string newpath = System.IO.Path.Combine(path, System.IO.Path.GetDirectoryName(entry.getName()));

                            System.IO.Directory.CreateDirectory(newpath);

                            java.io.FileOutputStream dest = new java.io.FileOutputStream(System.IO.Path.Combine(newpath, fname));
                            try
                            {
                                CopyStream(s, dest);
                            }
                            finally
                            {
                                dest.close();
                            }
                        }
                        finally
                        {
                            s.close();
                        }
                    }
                }
            }
        }

        ///


        /// 创建新的Zip文件
        ///

        /// Zip文件的路径
        /// Zip文件的路径
        public static ZipFile CreateEmptyZipFile(string fileName)
        {
            new ZipOutputStream(new java.io.FileOutputStream(fileName)).close();
            return new ZipFile(fileName);
        }

        ///


        /// 向存在的Zip文件中添加待紧缩的文件
        ///

        /// Zip文件
        ///
        /// 待紧缩的文件的路径
        ///
        public static ZipFile UpdateZipFile(ZipFile file, FilterEntryMethod filter, string[] newFiles)
        {
            string prev = file.getName();
            string tmp = System.IO.Path.GetTempFileName();
            ZipOutputStream to = new ZipOutputStream(new java.io.FileOutputStream(tmp));
            try
            {
                CopyEntries(file, to, filter);
                // add entries here
                if (newFiles != null)
                {
                    foreach (string f in newFiles)
                    {
                        ZipEntry z = new ZipEntry(f.Remove(0, System.IO.Path.GetPathRoot(f).Length));
                        z.setMethod(ZipEntry.DEFLATED);
                        to.putNextEntry(z);
                        try
                        {
                            java.io.FileInputStream s = new java.io.FileInputStream(f);
                            try
                            {
                                CopyStream(s, to);
                            }
                            finally
                            {
                                s.close();
                            }
                        }
                        finally
                        {
                            to.closeEntry();
                        }
                    }
                }
            }
            finally
            {
                to.close();
            }
            file.close();

            // now replace the old file with the new one
            System.IO.File.Copy(tmp, prev, true);
            System.IO.File.Delete(tmp);

            return new ZipFile(prev);
        }

        public static void CopyEntries(ZipFile , ZipOutputStream to)
        {
            CopyEntries(, to, null);
        }

        public static void CopyEntries(ZipFile , ZipOutputStream to, FilterEntryMethod filter)
        {
            foreach (ZipEntry entry in new EnumerationAdapter(new EnumerationMethod(.entries)))
            {
                if (filter == null || filter(entry))
                {
                    java.io.InputStream s = .getInputStream(entry);
                    try
                    {
                        to.putNextEntry(entry);
                        try
                        {
                            CopyStream(s, to);
                        }
                        finally
                        {
                            to.closeEntry();
                        }
                    }
                    finally
                    {
                        s.close();
                    }
                }
            }
        }
    }
}

应用国外开源加压解压库ICSharpCode.SharpZipLib实现加压,该库的官方网站为

http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

应用体验:可以照着例子实现简单的加压解压,可以加压一个文件夹中的所有文件,但没有供给加压子文件夹的申明。
今朝网上的一些代码有的无法加压空文件夹,有的加压了用rar解不开,这是一点须要改进的。
但若是只须要加压文件夹第一级子目次中的“文件”(不包含文件夹和子目次)的景象,应用这个库是很便利的。并且是正常zip格局。
比.Net供给的GZipStream类强在它可以遵守标准zip格局加压多个文件,而GZipStream没有供给加压多个文件的办法,须要本身定义,
如许解压也只有应用本身的法度才可以,通用性方面不如SharpZipLib。

 代码如下 复制代码

#region 加压解压办法
        ///


        /// 功能:紧缩文件(临时只紧缩文件夹下一级目次中的文件,文件夹及其子级被忽视)
        ///

        /// 被紧缩的文件夹夹路径
        /// 生成紧缩文件的路径,为空则默认与被紧缩文件夹同一级目次,名称为:文件夹名+.zip
        /// 失足信息
        /// 是否紧缩成功
        public bool ZipFile(string dirPath, string zipFilePath, out string err)
        {
            err = "";
            if (dirPath == string.Empty)
            {
                err = "要紧缩的文件夹不克不及为空!";
                return false;
            }
            if (!Directory.Exists(dirPath))
            {
                err = "要紧缩的文件夹不存在!";
                return false;
            }
            //紧缩文件名为空时应用文件夹名+.zip
            if (zipFilePath == string.Empty)
            {
                if (dirPath.EndsWith(""))
                {
                    dirPath = dirPath.Substring(0, dirPath.Length - 1);
                }
                zipFilePath = dirPath + ".zip";
            }

            try
            {
                string[] filenames = Directory.GetFiles(dirPath);
                using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilePath)))
                {
                    s.SetLevel(9);
                    byte[] buffer = new byte[4096];
                    foreach (string file in filenames)
                    {
                        ZipEntry entry = new ZipEntry(Path.GetFileName(file));
                        entry.DateTime = DateTime.Now;
                        s.PutNextEntry(entry);
                        using (FileStream fs = File.OpenRead(file))
                        {
                            int sourceBytes;
                            do
                            {
                                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                                s.Write(buffer, 0, sourceBytes);
                            } while (sourceBytes > 0);
                        }
                    }
                    s.Finish();
                    s.Close();
                }
            }
            catch (Exception ex)
            {
                err = ex.Message;
                return false;
            }
            return true;
        }

        ///


        /// 功能:解压zip格局的文件。
        ///

        /// 紧缩文件路径
        /// 解压文件存放路径,为空时默认与紧缩文件同一级目次下,跟紧缩文件同名的文件夹
        /// 失足信息
        /// 解压是否成功
        public bool UnZipFile(string zipFilePath, string unZipDir, out string err)
        {
            err = "";
            if (zipFilePath == string.Empty)
            {
                err = "紧缩文件不克不及为空!";
                return false;
            }
            if (!File.Exists(zipFilePath))
            {
                err = "紧缩文件不存在!";
                return false;
            }
            //解压文件夹为空时默认与紧缩文件同一级目次下,跟紧缩文件同名的文件夹
            if (unZipDir == string.Empty)
                unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
            if (!unZipDir.EndsWith(""))
                unZipDir += "";
            if (!Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);

            try
            {
                using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
                {

                    ZipEntry theEntry;
                    while ((theEntry = s.GetNextEntry()) != null)
                    {
                        string directoryName = Path.GetDirectoryName(theEntry.Name);
                        string fileName = Path.GetFileName(theEntry.Name);
                        if (directoryName.Length > 0)
                        {
                            Directory.CreateDirectory(unZipDir + directoryName);
                        }
                        if (!directoryName.EndsWith(""))
                            directoryName += "";
                        if (fileName != String.Empty)
                        {
                            using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
                            {

                                int size = 2048;
                                byte[] data = new byte[2048];
                                while (true)
                                {
                                    size = s.Read(data, 0, data.Length);
                                    if (size > 0)
                                    {
                                        streamWriter.Write(data, 0, size);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }//while
                }
            }
            catch (Exception ex)
            {
                err = ex.Message;
                return false;
            }
            return true;
        }//解压停止
        #endregion

须要添加对SharpZipLib的引用:

 代码如下 复制代码

using ICSharpCode.SharpZipLib.Zip;

相关文章

精彩推荐