当前位置: 移动技术网 > IT编程>开发语言>.net > asp.NET中实现文件的压缩和解压(3种方式)

asp.NET中实现文件的压缩和解压(3种方式)

2017年12月12日  | 移动技术网IT编程  | 我要评论

踢要害,防水监控,孙娆娆

在.net可以通过多种方式实现zip的压缩和解压:1、使用system.io.packaging;2、使用第三方类库;3、通过 system.io.compression 命名空间中新增的ziparchive、zipfile等类实现。

一、使用system.io.packaging压缩和解压

package为一个抽象类,可用于将对象组织到定义的物理格式的单个实体中,从而实现可移植性与高效访问。zip 文件是package的主物理格式。 其他package实现可以使用其他物理格式(如 xml 文档、数据库或 web 服务。与文件系统类似,在分层组织的文件夹和文件中引用 package 中包含的项。虽然 package 是抽象类,但 package.open 方法默认使用 zippackage 派生类。

system.io.packaging在windowsbase.dll程序集下,使用时需要添加对windowsbase的引用。

 1、将整个文件夹压缩成zip

 /// <summary>
  /// add a folder along with its subfolders to a package
  /// </summary>
  /// <param name="foldername">the folder to add</param>
  /// <param name="compressedfilename">the package to create</param>
  /// <param name="overrideexisting">override exsisitng files</param>
  /// <returns></returns>
  static bool packagefolder(string foldername, string compressedfilename, bool overrideexisting)
  {
   if (foldername.endswith(@"\"))
    foldername = foldername.remove(foldername.length - 1);
   bool result = false;
   if (!directory.exists(foldername))
   {
    return result;
   }

   if (!overrideexisting && file.exists(compressedfilename))
   {
    return result;
   }
   try
   {
    using (package package = package.open(compressedfilename, filemode.create))
    {
     var filelist = directory.enumeratefiles(foldername, "*", searchoption.alldirectories);
     foreach (string filename in filelist)
     {
      
      //the path in the package is all of the subfolders after foldername
      string pathinpackage;
      pathinpackage = path.getdirectoryname(filename).replace(foldername, string.empty) + "/" + path.getfilename(filename);

      uri parturidocument = packurihelper.createparturi(new uri(pathinpackage, urikind.relative));
      packagepart packagepartdocument = package.createpart(parturidocument,"", compressionoption.maximum);
      using (filestream filestream = new filestream(filename, filemode.open, fileaccess.read))
      {
       filestream.copyto(packagepartdocument.getstream());
      }
     }
    }
    result = true;
   }
   catch (exception e)
   {
    throw new exception("error zipping folder " + foldername, e);
   }
   
   return result;
  }

2、将单个文件添加到zip文件中

 /// <summary>
  /// compress a file into a zip archive as the container store
  /// </summary>
  /// <param name="filename">the file to compress</param>
  /// <param name="compressedfilename">the archive file</param>
  /// <param name="overrideexisting">override existing file</param>
  /// <returns></returns>
  static bool packagefile(string filename, string compressedfilename, bool overrideexisting)
  {
   bool result = false;

   if (!file.exists(filename))
   {
    return result;
   }

   if (!overrideexisting && file.exists(compressedfilename))
   {
    return result;
   }

   try
   {
    uri parturidocument = packurihelper.createparturi(new uri(path.getfilename(filename), urikind.relative));
    
    using (package package = package.open(compressedfilename, filemode.openorcreate))
    {
     if (package.partexists(parturidocument))
     {
      package.deletepart(parturidocument);
     }

     packagepart packagepartdocument = package.createpart(parturidocument, "", compressionoption.maximum);
     using (filestream filestream = new filestream(filename, filemode.open, fileaccess.read))
     {
      filestream.copyto(packagepartdocument.getstream());
     }
    }
    result = true;
   }
   catch (exception e)
   {
    throw new exception("error zipping file " + filename, e);
   }
   
   return result;
  }

3、zip文件解压

/// <summary>
  /// extract a container zip. note: container must be created as open packaging conventions (opc) specification
  /// </summary>
  /// <param name="foldername">the folder to extract the package to</param>
  /// <param name="compressedfilename">the package file</param>
  /// <param name="overrideexisting">override existing files</param>
  /// <returns></returns>
  static bool uncompressfile(string foldername, string compressedfilename, bool overrideexisting)
  {
   bool result = false;
   try
   {
    if (!file.exists(compressedfilename))
    {
     return result;
    }

    directoryinfo directoryinfo = new directoryinfo(foldername);
    if (!directoryinfo.exists)
     directoryinfo.create();

    using (package package = package.open(compressedfilename, filemode.open, fileaccess.read))
    {
     foreach (packagepart packagepart in package.getparts())
     {
      extractpart(packagepart, foldername, overrideexisting);
     }
    }

    result = true;
   }
   catch (exception e)
   {
    throw new exception("error unzipping file " + compressedfilename, e);
   }
   
   return result;
  }

  static void extractpart(packagepart packagepart, string targetdirectory, bool overrideexisting)
  {
   string stringpart = targetdirectory + httputility.urldecode(packagepart.uri.tostring()).replace('\\', '/');

   if (!directory.exists(path.getdirectoryname(stringpart)))
    directory.createdirectory(path.getdirectoryname(stringpart));

   if (!overrideexisting && file.exists(stringpart))
    return;
   using (filestream filestream = new filestream(stringpart, filemode.create))
   {
    packagepart.getstream().copyto(filestream);
   }
  }

使用package压缩文件会在zip文件自动生成[content_type].xml,用来描述zip文件解压支持的文件格式。

  <?xml version="1.0" encoding="utf-8" ?> 
<types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
 <default extension="vsixmanifest" contenttype="text/xml" /> 
 <default extension="dll" contenttype="application/octet-stream" /> 
 <default extension="png" contenttype="application/octet-stream" /> 
 <default extension="txt" contenttype="text/plain" /> 
 <default extension="pkgdef" contenttype="text/plain" /> 
</types>

同样,如果zip文件不包含[content_type].xml文件,或者[content_type].xml文件不包含所对应扩展名的描述(手动添加的[content_type].xml也是可以),将无法解压文件。

 二、使用第三方类库

zip的压缩和解压使用比较的有sharpziplib和dotnetzip。

1、sharpziplib,也称为“#ziplib”,基于gpl开源,支持zip,gzip,tar和bzip2的压缩和解压缩。

支持.net 1.1,net 2.0(3.5、4.0).

(1)zip压缩

 public static void zip(string srcfile, string dstfile, int buffersize)
{
 filestream filestreamin = new filestream
 (srcfile, filemode.open, fileaccess.read);
 filestream filestreamout = new filestream
 (dstfile, filemode.create, fileaccess.write);
 zipoutputstream zipoutstream = new zipoutputstream(filestreamout);
 byte[] buffer = new byte<buffersize />;
 zipentry entry = new zipentry(path.getfilename(srcfile));
 zipoutstream.putnextentry(entry);
 int size;
 do
 {
  size = filestreamin.read(buffer, 0, buffer.length);
  zipoutstream.write(buffer, 0, size);
 } while (size > 0);
 zipoutstream.close();
 filestreamout.close();
 filestreamin.close();
}

(2)解压zip

  public static void unzip(string srcfile, string dstfile, int buffersize)
{
 filestream filestreamin = new filestream
 (srcfile, filemode.open, fileaccess.read);
 zipinputstream zipinstream = new zipinputstream(filestreamin);
 zipentry entry = zipinstream.getnextentry();
 filestream filestreamout = new filestream
 (dstfile + @"\" + entry.name, filemode.create, fileaccess.write);
 int size;
 byte[] buffer = new byte<buffersize />;
 do
 {
  size = zipinstream.read(buffer, 0, buffer.length);
  filestreamout.write(buffer, 0, size);
 } while (size > 0);
 zipinstream.close();
 filestreamout.close();
 filestreamin.close();
}

2、dotnetlib,是基于”ws-pl”开源,使用比较简单

(1)压缩

  using (zipfile zip = new zipfile())
 {
 zip.addfile("readme.txt");
 zip.addfile("7440-n49th.png");
 zip.addfile("2008_annual_report.pdf");  
 zip.save("archive.zip");
 }

(2)解压

 private void myextract()
 {
  string ziptounpack = "c1p3sml.zip";
  string unpackdirectory = "extracted files";
  using (zipfile zip1 = zipfile.read(ziptounpack))
  {
   // here, we extract every entry, but we could extract conditionally
   // based on entry name, size, date, checkbox status, etc. 
   foreach (zipentry e in zip1)
   {
   e.extract(unpackdirectory, extractexistingfileaction.overwritesilently);
   }
  }
 }

三、在.net 4.5使用ziparchive、zipfile等类压缩和解压

 static void main(string[] args)
  {
   string zippath = @"c:\users\exampleuser\start.zip";
   string extractpath = @"c:\users\exampleuser\extract";
   string newfile = @"c:\users\exampleuser\newfile.txt";

   using (ziparchive archive = zipfile.open(zippath, ziparchivemode.update))
   {
    archive.createentryfromfile(newfile, "newentry.txt");
    archive.extracttodirectory(extractpath);
   } 
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网