返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >如何用C#实现压缩文件
  • 670
分享到

如何用C#实现压缩文件

2024-04-02 19:04:59 670人浏览 八月长安
摘要

目录一、单文件压缩二、多文件压缩三、多文件异步压缩四、压缩文件夹一、单文件压缩 场景,文件可能比较大,需要压缩传输,比如上传和下载 /// <summary> ///

一、单文件压缩

场景,文件可能比较大,需要压缩传输,比如上传和下载


/// <summary>
/// 单文件压缩
/// </summary>
/// <param name="sourceFile">源文件</param>
/// <param name="zipedFile">zip压缩文件</param>
/// <param name="blockSize">缓冲区大小</param>
/// <param name="compressionLevel">压缩级别</param>
public static void ZipFile(string sourceFile, string zipedFile, int blockSize = 1024, int compressionLevel = 6)
{
    if (!File.Exists(sourceFile))
    {
        throw new System.IO.FileNotFoundException("The specified file " + sourceFile + " could not be found.");
    }
    var fileName = System.IO.Path.GetFileNameWithoutExtension(sourceFile);

    FileStream streamToZip = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
    FileStream zipFile = File.Create(zipedFile);
    ZipOutputStream zipStream = new ZipOutputStream(zipFile);

    ZipEntry zipEntry = new ZipEntry(fileName);
    zipStream.PutNextEntry(zipEntry);

    //存储、最快、较快、标准、较好、最好  0-9
    zipStream.SetLevel(compressionLevel);

    byte[] buffer = new byte[blockSize];

    int size = streamToZip.Read(buffer, 0, buffer.Length);
    zipStream.Write(buffer, 0, size);
    try
    {
        while (size < streamToZip.Length)
        {
            int sizeRead = streamToZip.Read(buffer, 0, buffer.Length);
            zipStream.Write(buffer, 0, sizeRead);
            size += sizeRead;
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    zipStream.Finish();
    zipStream.Close();
    streamToZip.Close();
}

说明:26行,blocksize为缓存区大小,不能设置太大,如果太大也会报异常。26-38行,把文件通过FileStream流,读取到缓冲区中,再写入到ZipOutputStream流。你可以想象,两个管道,一个读,另一个写,中间是缓冲区,它们的工作方式是同步的方式。想一下,能不能以异步的方式工作,读的管道只管读,写的管道只管写?如果是这样一个场景,读的特别快,写的比较慢,比如,不是本地写,而是要经过网络传输,就可以考虑异步的方式。怎么做,读者可以自行改造。关键一点,流是有顺序的,所以要保证顺序的正确性即可。

二、多文件压缩

这种场景也是比较多见,和单文件压缩类似,无非就是多循环几次。


/// <summary>
/// 多文件压缩
/// </summary>
/// <param name="zipfile">zip压缩文件</param>
/// <param name="filenames">源文件集合</param>
/// <param name="passWord">压缩加密</param>
public void ZipFiles(string zipfile, string[] filenames, string password = "")
{
    ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(zipfile));

    s.SetLevel(6);

    if (password != "")
        s.Password = Md5Help.Encrypt(password);

    foreach (string file in filenames)
    {
        //打开压缩文件
        FileStream fs = File.OpenRead(file);

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

        var name = Path.GetFileName(file);

        ZipEntry entry = new ZipEntry(name);
        entry.DateTime = DateTime.Now;
        entry.Size = fs.Length;
        fs.Close();
        s.PutNextEntry(entry);
        s.Write(buffer, 0, buffer.Length);
    }
    s.Finish();
    s.Close();
}

说明:21行,缓冲区大小直接为文件大小,所以一次读完,没有循环读写。这种情况下,单个文件不能太大,比如超过1G。14行,可以为压缩包设置密码,MD5的生成方法如下:


public class Md5Help
{
    /// <summary>
    ///32位 MD5加密
    /// </summary>
    /// <param name="str">加密字符</param>
    /// <returns></returns>
    public static string Encrypt(string str)
    {
        MD5 md5 = new MD5CryptoServiceProvider();

        byte[] encryptdata = md5.ComputeHash(Encoding.UTF8.GetBytes(str));

        return Convert.ToBase64String(encryptdata);
    }
}

三、多文件异步压缩

上面同步的压缩的前提是,假设文件不大,而且文件数不多,但是现实是,不光文件大,而且文件数比较多。这种情况,就要考虑异步方法了。否则会阻塞主线程,就是我们平常说的卡死


/// <summary>
/// 异步压缩文件为zip压缩包
/// </summary>
/// <param name="zipfile">压缩包存储路径</param>
/// <param name="filenames">文件集合</param>
public static async void ZipFilesAsync(string zipfile, string[] filenames)
{
    await Task.Run(() =>
    {
        ZipOutputStream s = null;
        try
        {
            s = new ZipOutputStream(System.IO.File.Create(zipfile));

            s.SetLevel(6); // 0 - store only to 9 - means best compression 

            foreach (string file in filenames)
            {
                //打开压缩文件 
                FileStream fs = System.IO.File.OpenRead(file);

                var name = Path.GetFileName(file);
                ZipEntry entry = new ZipEntry(name);
                entry.DateTime = DateTime.Now;
                entry.Size = fs.Length;
                s.PutNextEntry(entry);

                //如果文件大于1G
                long blockSize = 51200;

                var size = (int)fs.Length;

                var oneG = 1024 * 1024 * 1024;

                if (size > oneG)
                {
                    blockSize = oneG;
                }
                byte[] buffer = new byte[blockSize];

                size = fs.Read(buffer, 0, buffer.Length);

                s.Write(buffer, 0, size);

                while (size < fs.Length)
                {
                    int sizeRead = fs.Read(buffer, 0, buffer.Length);
                    s.Write(buffer, 0, sizeRead);
                    size += sizeRead;
                }
                s.Flush();
                fs.Close();
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("异步压缩文件出错:" + ex.Message);
        }
        finally
        {
            s?.Finish();
            s?.Close();
        }
    });
}

四、压缩文件夹

实际的应用当中,是文件和文件夹一起压缩,所以这种情况,就干脆把要压缩的东西全部放到一个文件夹,然后进行压缩。

主方法如下:


/// <summary>
/// 异步压缩文件夹为zip压缩包
/// </summary>
/// <param name="zipfile">压缩包存储路径</param>
/// <param name="sourceFolder">压缩包存储路径</param>
/// <param name="filenames">文件集合</param>
public static async void ZipFolderAsync(string zipfile, string sourceFolder, string[] filenames)
{
    await Task.Run(() =>
    {
        ZipOutputStream s = null;
        try
        {
            s = new ZipOutputStream(System.IO.File.Create(zipfile));

            s.SetLevel(6); // 0 - store only to 9 - means best compression 

            CompressFolder(sourceFolder, s, sourceFolder);
        }
        catch (Exception ex)
        {
            Console.WriteLine("异步压缩文件出错:" + ex.Message);
        }
        finally
        {
            s?.Finish();
            s?.Close();
        }
    });
}

压缩的核心方法:


/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="source">源目录</param>
/// <param name="s">ZipOutputStream对象</param>
/// <param name="parentPath">和source相同</param>
public static void CompressFolder(string source, ZipOutputStream s, string parentPath)
{
    string[] filenames = Directory.GetFileSystemEntries(source);
    foreach (string file in filenames)
    {
        if (Directory.Exists(file))
        {
            CompressFolder(file, s, parentPath);  //递归压缩子文件夹
        }
        else
        {
            using (FileStream fs = System.IO.File.OpenRead(file))
            {
                var writeFilePath = file.Replace(parentPath, "");
                ZipEntry entry = new ZipEntry(writeFilePath);
                entry.DateTime = DateTime.Now;
                entry.Size = fs.Length;

                s.PutNextEntry(entry);

                //如果文件大于1G
                long blockSize = 51200;

                var size = (int)fs.Length;

                var oneG = 1024 * 1024 * 1024;

                if (size > oneG)
                {
                    blockSize = oneG;
                }
                byte[] buffer = new byte[blockSize];

                size = fs.Read(buffer, 0, buffer.Length);

                s.Write(buffer, 0, size);


                while (size < fs.Length)
                {
                    int sizeRead = fs.Read(buffer, 0, buffer.Length);
                    s.Write(buffer, 0, sizeRead);
                    size += sizeRead;
                }

                s.Flush();   //清除流的缓冲区,使得所有缓冲数据都写入到文件中
                fs.Close();
            }
        }
    }
}

唯一需要注意的地方,可能解压出来的目录结构和压缩前的文件目录不同,这时候检查parentPath参数,它在ZipEntry实体new的时候用,替换绝对路径为当前的相对路径,也就是相对压缩文件夹的路径。

上面的方法比较复杂,还有一种相对简单的方式,直接调用api


public static string ZipFolder(string sourceFolder, string zipFile)
{
    string result = "";
    try
    {
        //创建压缩包
        if (!Directory.Exists(sourceFolder)) return result = "压缩文件夹不存在";

        DirectoryInfo d = new DirectoryInfo(sourceFolder);
        var files = d.GetFiles();
        if (files.Length == 0)
        {
            //找子目录
            var ds = d.GetDirectories();
            if (ds.Length > 0)
            {
                files = ds[0].GetFiles();
            }
        }
        if (files.Length == 0) return result = "待压缩文件为空";
        System.IO.Compression.ZipFile.CreateFromDirectory(sourceFolder, zipFile);
    }
    catch (Exception ex)
    {
        result += "压缩出错:" + ex.Message;
    }
    return result;
}

以上就是如何用C#实现压缩文件的详细内容,更多关于C#压缩文件的资料请关注编程网其它相关文章!

--结束END--

本文标题: 如何用C#实现压缩文件

本文链接: https://lsjlt.com/news/129338.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何用C#实现压缩文件
    目录一、单文件压缩二、多文件压缩三、多文件异步压缩四、压缩文件夹一、单文件压缩 场景,文件可能比较大,需要压缩传输,比如上传和下载 /// <summary> ///...
    99+
    2024-04-02
  • Android如何实现压缩和解压缩文件
    废话不多说了,直接给大家贴java代码了,具体代码如下所示: Java代码 package com.maidong.utils; import java.io.Buffe...
    99+
    2022-06-06
    压缩 解压 Android
  • C#如何实现多文件打包压缩
    C#如何实现多文件打包压缩,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。最近项目需要实现多文件打包的功能,尝试了一些方法,最后发现使用ICSharpCode.S...
    99+
    2023-06-22
  • 怎么用C#实现压缩文件
    本篇内容主要讲解“怎么用C#实现压缩文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用C#实现压缩文件”吧!一、单文件压缩场景,文件可能比较大,需要压缩传输,比如上传和下载/// ...
    99+
    2023-06-20
  • Java如何实现文件压缩为zip和解压zip压缩包
    本篇内容介绍了“Java如何实现文件压缩为zip和解压zip压缩包”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!压缩成.zip代码如下:pu...
    99+
    2023-07-02
  • C#实现多文件压缩与解压功能
    目录实现功能开发环境实现代码实现效果这个功能没什么可介绍的,大家都懂,直接上代码了。。 实现功能 选择多个文件压缩成ZIP文件和解压ZIP文件 开发环境 开发工具: Visual S...
    99+
    2024-04-02
  • C#使用SharpZipLib压缩解压文件
    一、介绍 SharpZipLib是一个完全由C#编写的ZIP,GZIP,Tar和BZIP2 Library,可以方便的支持这几种格式的压缩和解压缩。 https://github.c...
    99+
    2024-04-02
  • Java 如何实现解压缩文件和文件夹
    目录一 前言 二 压缩文件 2.1 压缩多个文件 2.2 压缩文件或文件树 2.3 借助文件访问器压缩 三 解压文件 四 总结 一 前言 项目开发中,总会遇到解压缩文件的时候。比如...
    99+
    2024-04-02
  • c# 用ICSharpCode组件压缩文件
    目录一、单文件压缩二、多文件压缩三、多文件异步压缩四、压缩文件夹一、单文件压缩       场景,文件可能比较大,需要压缩传输,比如上传和下载 //...
    99+
    2024-04-02
  • C#通过cmd调用7z软件实现压缩和解压文件
    压缩文件: public object CompressZipFile(string sourceFile, string destinationFile) { ...
    99+
    2024-04-02
  • C#实现多文件打包压缩(.Net Core)
    最近项目需要实现多文件打包的功能,尝试了一些方法,最后发现使用ICSharpCode.SharpZipLib 最符合项目的要求。 具体实现如下: 1.在 Nuget 中安装ICSha...
    99+
    2024-04-02
  • 里有Java如何实现压缩与解压zip文件
    里有Java如何实现压缩与解压zip文件?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java解压缩zip - 多个文件(包括文件夹),对多个文件和文件夹进行压...
    99+
    2023-05-31
    java ava zip
  • 如何在C#中压缩和解压rar、zip文件
    这期内容当中小编将会给大家带来有关如何在C#中压缩和解压rar、zip文件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在C#.NET中压缩解压rar文件rar格式是一种具有专利文件的压缩格式,是一种商业...
    99+
    2023-06-15
  • Python底层技术揭秘:如何实现文件压缩与解压缩
    Python底层技术揭秘:如何实现文件压缩与解压缩文件压缩与解压缩是我们在日常开发中经常需要处理的任务之一。Python作为一种强大的编程语言,提供了丰富的库和模块来处理文件操作,其中包括文件压缩与解压缩的功能。本文将揭秘Python底层技...
    99+
    2023-11-09
    Python 解压缩 文件压缩 底层技术
  • PDF文件如何压缩
    小编给大家分享一下PDF文件如何压缩,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!  步骤一:打开压缩工具,在跳转的页面有五个功...
    99+
    2024-04-02
  • wps如何压缩文件
    这篇文章主要介绍wps如何压缩文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!wps压缩文件的方法:1、在wps软件中打开想要压缩的文件;2、选择点击顶部导航栏中的“工具”选项;3、在打开的菜单中点击“文件瘦身”选...
    99+
    2023-06-14
  • bandizip如何压缩文件
    这篇文章主要介绍了bandizip如何压缩文件的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇bandizip如何压缩文件文章都会有所收获,下面我们一起来看看吧。 bandiz...
    99+
    2023-04-13
    bandizip
  • C++项目基于HuffmanTree实现文件的压缩与解压缩功能
    目录前言1.文件压缩的概念2.为什么需要压缩3.压缩的分类4.压缩的方法二、HuffmanTree文件压缩与解压缩1.HuffmanTree的概念2.HuffmanTree的构建3....
    99+
    2024-04-02
  • 怎么用java实现压缩文件
    你可以使用Java的ZipOutputStream类来压缩文件。下面是一个简单的例子: import java.io.File; i...
    99+
    2023-10-23
    java
  • Java实现文件压缩为zip和解压zip压缩包
    目录压缩成.zip解压.zip压缩成.zip 代码如下: public static void toZip(String srcDir, OutputStream out) th...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作