asp.net实现zip压缩与解压缩
在.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在window易做图ase.dll程序集下,使用时需要添加对window易做图ase的引用。
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文件解压支持的文件格式。
<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压缩
{
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
{
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)、压缩
{
zip.addfile("readme.txt");
zip.addfile("7440-n49th.png");
zip.addfile("2008_annual_report.pdf");
zip.save("archive.zip");
}
2)、解压缩
{
string ziptounpack = "c1p3易做图l.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 = @"d:\zzzyk.com.zip";
string extractpath = @"d:\zzzyk.com";
string newfile = @"d:\zzzyk.com\newfile.txt";
using (ziparchive archive = zipfile.open(zippath, ziparchivemode.update))
{
archive.createentryfromfile(newfile, "newentry.txt");
archive.extracttodirectory(extractpath);
}
}