asp.NET中实现文件的压缩和解压(3种方式)
在.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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。