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();
            }
        }

  

 

转载于:https://www.cnblogs.com/sgciviolence/p/5608414.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值