zoukankan      html  css  js  c++  java
  • 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();
                }
            }
    

      

  • 相关阅读:
    void die(const char *msg)
    [C] Re-execute itself from elf file.
    在cnblog中使用syntax方法
    CVE-2016-0822-MTK-drivers/misc/mediatek/connectivity/common/combo/linux/wmt_dev.c#1158
    CVE-2016-2502-drivers/usb/gadget/f_serial.c in the Qualcomm USB driver in Android. Buffer Overflow Vulnerability reported by #plzdonthackme, Soctt.
    Insertion Sort
    [Java] 歐付寶金流串接教學
    [面試題]C符號的優先順序
    [LeetCode]Search a 2D Matrix
    [leetcode] Search a 2D Matrix II
  • 原文地址:https://www.cnblogs.com/sgciviolence/p/5608414.html
Copyright © 2011-2022 走看看