使用SharpZipLib壓縮打包多個內存中的文件

SharpZipLib是C#寫的開源壓縮解壓縮組件,最近項目上遇到一個需求:根據用戶選擇的項目生成CSV文件並下載,後來改爲同時生成2個CSV文件下載下來。想到的解決辦法就是將2個CSV文件打包成一個Zip文件,然後供用戶下載。

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接口的方式來打包。

發佈了224 篇原創文章 · 獲贊 5 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章