SharpZipLib.dll 压缩文件,可以应用于MVC, webform. C# windows application 等等地方

Nuget 安装:Install-Package ICSharpCode.SharpZipLib.dll

private void WriteZipFile(string[] filesToZip, string writeToFilePath)
{
    try
    {
        Crc32 crc = new Crc32();
        ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(writeToFilePath));
        s.SetLevel(9); // 0 - store only to 9 - means best compression
        for (int i = 0; i < filesToZip.Length; i++)
        {
            // Must use a relative path here so that files show up in the Windows Zip File Viewer
            // .. hence the use of Path.GetFileName(...)
            ZipEntry entry = new ZipEntry(Path.GetFileName(filesToZip[i]));
            entry.DateTime = DateTime.Now;

            // Read in the 
            using (FileStream fs = System.IO.File.OpenRead(filesToZip[i]))
            {

                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);

                // set Size and the crc, because the information
                // about the size and crc should be stored in the header
                // if it is not set it is automatically written in the footer.
                // (in this case size == crc == -1 in the header)
                // Some ZIP programs have problems with zip files that don't store
                // the size and crc in the header.
                entry.Size = fs.Length;
                fs.Close();

                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;
                s.PutNextEntry(entry);
                s.Write(buffer, 0, buffer.Length);
            }
        }

        s.Finish();
        s.Close();

    }
    catch (Exception ex)
    {
        HttpContext.Trace.Warn(ex.ToString());
    }
}

  

 今天经过大文件压缩测试,发现这里有一个内存溢出的bug,当文件大于500M左右时,

 byte[] buffer = new byte[fs.Length]; //会发生内存溢出

经查资料,解决方法是,边读文件流边压缩,这样就可以避免Web服务器一次性都到的内存里,如果先把文件压缩到MemoryStream,最后在输出就会消耗大量的内存在MemoryStream里。也就容易引起内存溢出了

private void WriteZipFile(string[] filesToZip, string writeToFilePath)
{
    try
    { 
        Stream fs1 = System.IO.File.OpenWrite(writeToFilePath);
        ZipOutputStream s = new ZipOutputStream(fs1);
        s.SetLevel(9); // 0 - store only to 9 - means best compression
        for (int i = 0; i < filesToZip.Length; i++)
        {           
            ZipEntry entry = new ZipEntry(Path.GetFileName(filesToZip[i]));
            entry.DateTime = DateTime.Now;           
            using (var fs = new FileStream(filesToZip[i], FileMode.Open, FileAccess.Read))
            {
                entry.Size = fs.Length; //这个时候是没用把文件读到内存里的
                s.PutNextEntry(entry);
                        
                byte[] buffer = new byte[10240]; //边读边写
                int bytesRead = 0;
                while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    s.Write(buffer, 0, bytesRead);
                }
                s.CloseEntry();
            } 
        }
        s.Finish();
        s.Close();
        fs1.Close();
    }
    catch (Exception ex)
    {
        HttpContext.Trace.Warn(ex.ToString());
    }
}

MVC 输出:File(Server.MapPath("文件路径"), "application/zip", "文件名");

WebForm 输出同样要避免500M文件容易出现的内存溢出:

        public void DownloadFile(string physicalFilePath)
        {
            FileStream stream = null;
            try
            {
                stream = new FileStream(physicalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                 
                byte[] buffer = new byte[10240];
                int bytesRead = 0;
                while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    HttpContext.Response.OutputStream.Write(buffer, 0, bytesRead);
                }
                HttpContext.Response.ContentType = "application/octet-stream ";
                HttpContext.Response.AppendHeader("Content-Disposition ", "attachment;filename= " + System.IO.Path.GetFileName(physicalFilePath));
                
                HttpContext.Response.End();
            }
            finally
            {
                stream.Close();
            }
        }

  

 

posted @ 2016-06-22 20:28  violence  阅读(415)  评论(0编辑  收藏  举报