SharpZipLib可以通過很簡單的代碼就將多個文件打包成一個zip包,形如:
using (ZipFile zip = ZipFile.Create(@"E:\test.zip"))
{
zip.BeginUpdate();
ZipEntry e=new ZipEntry("a");
//添加文件
zip.Add(@"E:\a.csv");
zip.Add(@"E:\b.csv");
zip.CommitUpdate();
}
但是這裏的問題是,zip.Add方法允許添加文件,但是不允許直接添加字符串或者byte[],但是我們做的是WebApplication,不希望是在Web服務器上把兩個CSV文件生成後保存到硬盤上,然後調用上面的方法壓縮硬盤上的文件。我們的文件應該都是在內存中生成,在內存中打包,然後直接把生成的zip文件的二進制流返回給用戶,讓用戶下載。幸好該方法提供了一個IStaticDataSource接口參數,該接口有個返回Stream的GetSource方法,我們可以實現該接口,從而支持字符串文件的打包。
class StringDataSource : IStaticDataSource
{
public string Str { get; set; }
public StringDataSource(string str)
{
this.Str = str;
}
public Stream GetSource()
{
Stream s = new MemoryStream(Encoding.Default.GetBytes(Str));
return s;
}
}
實現了該接口後,那麼我們壓縮兩個String成兩個文本文件的包,代碼就十分簡單了:
using (ZipFile zip = ZipFile.Create(@"E:\test2.zip"))
{
zip.BeginUpdate();
StringDataSource d1 = new StringDataSource("this a test1");
StringDataSource d2 = new StringDataSource("壓縮文件2的內容");
//添加文件
zip.Add(d1, "Test1.txt");
zip.Add(d2, "Test2.txt");
zip.CommitUpdate();
}
上面的代碼還是在硬盤上生成了test2.zip,幸好ZipFile.Create方法支持Stream參數,於是可以將代碼改爲:
MemoryStream stream=new MemoryStream();
using (ZipFile zip = ZipFile.Create(stream))
{
zip.BeginUpdate();
StringDataSource d1 = new StringDataSource("this a test1");
StringDataSource d2 = new StringDataSource("壓縮文件2的內容");
//添加文件
zip.Add(d1, "Test1.txt");
zip.Add(d2, "Test2.txt");
zip.CommitUpdate();
}
然後將stream繼續Render給用戶即可。
同樣的方式,如果是在內存中生成了二進制文件,也可以使用實現IStaticDataSource接口的方式來打包。