NetCore 批量下载文件打包压缩,多个文件流保存本地,盗链技术

在使用文件下载的时候,很多情况都会需要下载文件的功能,单个文件的下载当然很简单,若是多个文件的下载就稍微有一点复杂,若是微服务架构,需要下载文件或者压缩打包文件,那就更加复杂了。

研究了一天,终于实现了功能。这会儿终于得空,记录一下。以便日后参考

打包下载主要出现两种情况

1:本地文件打包下载,一台服务器,很简单,不做过多的记录说明

2:微服务/其他文件服务器,打包下载文件流并压缩

使用 ZipFile压缩 类,必须在项目中引用 System.IO.Compression.FileSystem 程序集。

 

2的实现思路:

1:远程获取到文件流

2:本地创建需要保存的文件目录以及压缩包名

3:复制文件流到需要保存的文件目录下

4:使用ZipFile压缩目录中的所有文件,保存为一个压缩包

5:删除之前创建的文件目录以及子目录(防止过多下载,造成文件堆积过多)

6:返回前端压缩包的地址,通过window.open(压缩包的地址)下载

以下为核心代码:


        [HttpPost]
        public async Task<IActionResult> OnPostDown([FromBody]JObject value)
        {
            if (value["value"]!=null)
            {
                //先判断是否保存有上次的下载压缩文件
                if (System.IO.File.Exists(Directory.GetCurrentDirectory() + "/wwwroot/ziliao.zip"))
                {
                    System.IO.File.Delete(Directory.GetCurrentDirectory() + "/wwwroot/ziliao.zip");
                }
                var pathZip = Directory.GetCurrentDirectory() + "/wwwroot/downfile/";
                //创建目录的文件路径

                //先根据资料创建文件目录,在循环添加文件在目录下
                var listData = JArray.Parse(value["value"].ToString());
                foreach (var item in listData)
                {
                    //获取远程资料数据集合
                    var fileList = await BaseGetRequestAsync<PagedResponseDto<DataFileDto>>("/api/UnionData/fileList/" + item["RecordId"].ToString(), null);
                    //获取资料名称,--同时创建资料目录
                    var dicName = item["Name"].ToString();
                    var newPath = pathZip + dicName;
                    if (!Directory.Exists(newPath))
                    {
                        Directory.CreateDirectory(newPath);
                    }

                    foreach (var fitem in fileList.Data)
                    {
                        //循环文件信息集合
                        var path = BaseGetApiUrlByName("RemoteFileUpload");
                        //文件请求地址
                        path += fitem.FilePath;
                        HttpClient client = new HttpClient();
                        client.BaseAddress = new Uri(path);
                        //根据文件信息中的文件地址获取远程服务器,返回文件流
                        var stream = await client.GetStreamAsync(path);
                        
                        var fils = File(stream, "application/vnd.android.package-archive", Path.GetFileName(path));
                        //创建文件流(文件路径,文件操作.创建)
                        using (FileStream fs = new FileStream(newPath+"/"+fitem.FileName, FileMode.Create))
                        {
                            //复制文件流
                            fils.FileStream.CopyTo(fs);
                        }
                    }
                }
                ZipFile.CreateFromDirectory(Directory.GetCurrentDirectory() + "/wwwroot/downfile/", Directory.GetCurrentDirectory() + "/wwwroot/" + "ziliao.zip");
                //删除目录以及目录下的子文件
                //存在即删除
                if (Directory.Exists(pathZip))
                {
                    Directory.Delete(pathZip, true);
                }
            }
            //返回压缩文件的路径
            return Json(new { hrefs= Url.Content("~/ziliao.zip") });
        }

前端调用代码

if (data.length > 0) {
                        //选中得数据,多个文件信息集合
                        var loadindex = layer.msg('打包中...', { icon: 16, shade: [0.5, '#f5f5f5'], scrollbar: false, offset: 'auto', time: 60000 });
                        console.log(data);
                        var postData = { value: data };
                        $.ajax({
                            url: "@Url.Content("~/UnionDataSearch/OnPostDown")",
                            type: "post",
                            dataType: "json",
                            contentType: "application/json",
                            data: JSON.stringify(postData),
                            success: function (res) {
                                layer.close(loadindex);
                                var resdata = eval(res);
                                console.log(res);
                                window.open(resdata.hrefs);
                                
                            }
                        })
                        //over_code
                    } else {
                        layer.msg("请选择至少一个选项")
                    }

最后压缩主要使用ZipFile类,该类的说明地址:https://docs.microsoft.com/zh-cn/dotnet/api/system.io.compression.zipfile?view=netcore-3.1

完美运行,整个流程测试没有任何的错误。

posted @ 2023-05-17 15:00  夜钓星云  阅读(311)  评论(0编辑  收藏  举报  来源