欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#实现多文件打包压缩(.Net Core)

程序员文章站 2022-06-10 15:05:57
最近项目需要实现多文件打包的功能,尝试了一些方法,最后发现使用icsharpcode.sharpziplib 最符合项目的要求。具体实现如下:1.在 nuget 中安装icsharpcode.shar...

最近项目需要实现多文件打包的功能,尝试了一些方法,最后发现使用icsharpcode.sharpziplib 最符合项目的要求。

具体实现如下:

1.在 nuget 中安装icsharpcode.sharpziplib

C#实现多文件打包压缩(.Net Core)

2.将要打包的文件放到同个文件夹进行压缩:

①压缩文件夹

/// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="filename">压缩后获得的文件名</param>
        public static bool compressfile(string dir, out string filename)
        {
            string dest = system.environment.getfolderpath(system.environment.specialfolder.desktop) + "\\" + string.format("{0:yyyymmddhhmmss}", datetime.now) + ".zip";   //默认压缩在桌面上
            if (!directory.exists(path.getdirectoryname(dest)))   //文件不存在就根据路径创建  e:\\test
                directory.createdirectory(path.getdirectoryname(dest));
            using (zipoutputstream zipstream = new zipoutputstream(file.create(dest)))
            {
                zipstream.setlevel(6);   //压缩级别0-9
                createzip(dir, zipstream);
                filename = dest;
                zipstream.finish();
                zipstream.close();
            }
            return true;
        }
        /// <summary>
        /// 压缩内容到 zipstream 流中
        /// </summary>
        /// <param name="source">源文件</param>
        /// <param name="zipstream">目标文件流(全路径+文件名+.zip)</param>

        private static void createzip(string source, zipoutputstream zipstream)
        {
            crc32 crc = new crc32();
            string[] files = directory.getfilesystementries(source);  //获得所有文件名称和目录名称
            foreach (var file in files)
            {
                if (directory.exists(file))    //如果是文件夹里有文件则递归
                {
                    createzip(file, zipstream);
                }
                else    //如果不是则压缩
                {
                    using (filestream fs = file.openread(file))
                    {
                        byte[] buffer = new byte[fs.length];
                        fs.read(buffer, 0, buffer.length);
                        string tempfilename = file.substring(file.lastindexof("\\") + 1);  //获得当前文件路径的文件名
                        zipentry entry = new zipentry(tempfilename);
                        entry.datetime = datetime.now;
                        entry.size = fs.length;
                        fs.close();
                        crc.reset();
                        crc.update(buffer);
                        entry.crc = crc.value;
                        zipstream.putnextentry(entry);
                        zipstream.write(buffer, 0, buffer.length);
                    }
                }
            }
        }

②将指定文件打包压缩 (可打包线上文件)

/// <summary>
        /// 打包线上线下文件
        /// </summary>
        /// <param name="filelist">文件列表</param>
        /// <param name="savepath">保存路径</param>
        public static void ziponlinefile3(list<string> filelist, string savepath)
        {
            //判断保存的文件目录是否存在
            if (!file.exists(savepath))
            {
                var file = new fileinfo(savepath);
                if (!file.directory.exists)
                {
                    file.directory.create();
                }
            }

            crc32 crc = new crc32();
            using (zipoutputstream zipstream = new zipoutputstream(file.create(savepath)))
            {
                zipstream.setlevel(9);   //压缩级别0-9  

                foreach (var url in filelist)
                {
                    byte[] buffer = new webclient().downloaddata(url);
                    string tempfilename = getfilenamebyurl(url);  //获得当前文件路径的文件名
                    zipentry entry = new zipentry(tempfilename);
                    entry.datetime = datetime.now;
                    entry.size = buffer.length;
                    crc.reset();
                    crc.update(buffer);
                    zipstream.putnextentry(entry);
                    zipstream.write(buffer, 0, buffer.length);
                }
            }
        }

从文件路径读取文件名的方法:

public static string getfilenamebyurl(string url)
        {
            //判断路径是否为空
            if (string.isnullorwhitespace(url)) return null;

            //判断是否为线上文件
            if (url.tolower().startswith("http"))
            {
                return url.substring(url.lastindexof("/") + 1);
            }
            else
            {
                return url.substring(url.lastindexof("\\") + 1);
            }
        }

通过此方法生成的压缩包,所有文件都会显示在同一层。

③如果需要在文件中创建目录,需要在文件名称上指定文件路径

添加工具类:

/// <summary>
    /// 文件对象
    /// </summary>
    public class fileitem
    {
        /// <summary>
        /// 文件名称
        /// </summary>
        public string filename { get; set; }
        /// <summary>
        /// 文件路径
        /// </summary>
        public string fileurl { get; set; }
    }

压缩文件的方法:

/// <summary>
        /// 打包线上线下文件
        /// </summary>
        /// <param name="zipname">压缩文件名称</param>
        /// <param name="filelist">文件列表</param>
        /// <param name="savepath">保存路径</param>
        public static string zipfiles(string zipname, list<fileitem> filelist, out string error)
        {
            error = string.empty;

            string path = string.format("/files/zipfiles/{0}/{1}/{2}/", datetime.now.year, datetime.now.month, datetime.now.day);
            //文件保存目录
            string directory = filesavepath + path;
            string url = filehosturl.trimend('/') + path + zipname;
            string savepath = directory + zipname;

            try
            {
                if (!directory.exists(directory))
                {
                    directory.createdirectory(directory);
                }

                using (zipoutputstream zipstream = new zipoutputstream(file.create(savepath)))
                {
                    zipstream.setlevel(9);   //压缩级别0-9

                    foreach (var item in filelist)
                    {
                        byte[] buffer = new webclient().downloaddata(item.fileurl);
                        zipentry entry = new zipentry(item.filename);
                        entry.datetime = datetime.now;
                        entry.size = buffer.length;
                        zipstream.putnextentry(entry);
                        zipstream.write(buffer, 0, buffer.length);
                    }
                }
            }
            catch (exception ex)
            {
                error = "文件打包失败:" + ex.message;
            }

            return url;
        }

调用参数示例:

{
  "zipname": "test.zip",
  "filelist": [
    {
      "filename": "123.png",
      "fileurl": "https://file.yidongcha.cn/files/uploadfiles/image/2021/11/15/11c6de395fcc484faf4745ade62cf6e6.png"
    },
    {
      "filename": "123/456/789.jpg",
      "fileurl": "https://file.yidongcha.cn/files/uploadfiles/image/2021/11/15/fe922b250acf4344b8ca4d2aad6e0355.jpg"
    }
  ]
}

生成的结果:

C#实现多文件打包压缩(.Net Core)

以上所述是小编给大家介绍的.net core框架下c#实现多文件打包压缩的方法,希望对大家有所帮助。在此也非常感谢大家对网站的支持!