NET8环境WebAPI实现文件的压缩及下载
目录
- 1、文件下载的原理
- 2、具体实现
- 2.1 提前准备
- 2.2 服务器端的实现
- 2.3 请求端的实现
- 3、代码下载
- 4、更多特性
- 4.1 单独压缩文件
- 4.2 解析
- 4.2.1 整体解析
- 4.2.2 单个文件解析
- 4.3 其他
- 4.3.1 设置压缩级别
- 4.3.2 密码保护
- 4.3.3 进度反馈
- 5、参考资料
1、文件下载的原理
在实际应用环境中,文件的下载是一个特别常见的需求。为了传输文件的大小,往往需要对文件进行压缩,因此就涉及到文件的压缩及文件的下载,具体步骤有5步。(1)、请求端发出文件的请求。这个可以根据实际需求,使用get/post及参数,发起一个请求。(2)、服务器收到请求后,会根据需求生成(或者准备)相关文件(最常用的例子就是:患者通过医院App下载处方、门诊记录单、诊断证明书之类)【这一步往往是偏向业务相关】。(3)然后将这些生成的文件,压缩成zip文件格式。(4)、服务端返回数据。(5)、客户端收到数据后,解析Response中的Stream,并使用FileStream将文件存储到本地。
具体的原理如下图所示

2、具体实现
2.1 提前准备
我们提前准备了文件(这步主要是模拟实际业务中生成的文件夹及文件)。在fhirs文件夹下有一个index.xml文件和emrfhirs文件夹,并且在emrfhirs文件夹内有001fhir.json、002fhir.json、003fhir.json三个文件。文档的目录结构如下:


2.2 服务器端的实现
创建webapi项目,实现下载文件的方法。具体代码如下
[HttpPost]
public async Task<ActionResult> getCompressionFile()
{try{/** 接收客户端的参数,本示例为了简化,不进行处理IFormCollection form = HttpContext.Request.Form;string? username = form["UserName"];string? password = form["Password"];string? remoteFilePath = form["RemotePath"];**/string source_folder = @"D:\data\fhirs"; //需要压缩的文件的路径,就是刚才上面提到的文件夹及文件string destination_path = @"D:\data\fhirsemr.zip"; //要将上面的文件夹变成的压缩文件// using System.IO.Compression;//将文件进行压缩await Task.Run(() =>{ZipFile.CreateFromDirectory(source_folder, destination_path);});//这个地方涉及一个知识//zip压缩文件,它的content-type是application/x-zip-compressed//rar压缩文件,它的content-type是application/octet-streamvar stream = new FileStream(destination_path, FileMode.Open, FileAccess.Read);return new FileStreamResult(stream, "application/x-zip-compressed"){FileDownloadName = "ermfile"};}catch (Exception ex){throw new Exception(ex.Message);}
}
上面就是服务端的代码
2.3 请求端的实现
客户端的请求端实现如下
//url:服务端的地址
//localFileFullPath:将文件存储到本地的路径
//otherParams:给业务使用的参数
private string GetFile(string url, string localFileFullPath, string otherParams)
{try{Uri uri = new Uri(url);HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);request.Method = "post"; //post、getrequest.ContentType = "application/x-www-form-urlencoded;charset=utf-8";request.KeepAlive = true;request.Credentials = CredentialCache.DefaultCredentials;using (Stream requestStream = request.GetRequestStream()){byte[] formDataBytes = Encoding.UTF8.GetBytes(otherParams);requestStream.Write(formDataBytes, 0, formDataBytes.Length);}HttpWebResponse response = (HttpWebResponse)request.GetResponse();//判断路径,并创建路径string path = Path.GetDirectoryName(localFileFullPath);if (!Directory.Exists(path) && !string.IsNullOrEmpty(path)){Directory.CreateDirectory(path);}//将文件using (FileStream fs = new FileStream(localFileFullPath, FileMode.Create, FileAccess.Write, FileShare.None)){using (Stream responseStream = response.GetResponseStream()){//创建本地文件写入流byte[] bArr = new byte[1024];int iTotalSize = 0;int size = responseStream.Read(bArr, 0, bArr.Length);while (size > 0){iTotalSize += size;fs.Write(bArr, 0, size);size = responseStream.Read(bArr, 0, bArr.Length);}}}return "Success-获取文件成功";}catch (Exception ex){return "Error-"+ex.Message;}
}
3、代码下载
代码比较简单,无代码
4、更多特性
4.1 单独压缩文件
如果你只想压缩特定的文件,而不是整个文件夹,你可以使用FileStream和ZipArchive来实现。实际上就是NET中的文件操作
using System.IO;
using System.IO.Compression;string startPath = @"c:\example\file.txt"; // 要压缩的文件路径
string zipPath = @"c:\example\result.zip"; // 压缩后的ZIP文件路径using (FileStream zipToOpen = new FileStream(zipPath, FileMode.Create))
{using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create)){ZipArchiveEntry readmeEntry = archive.CreateEntry("file.txt");using (StreamWriter writer = new StreamWriter(readmeEntry.Open())){using (StreamReader reader = new StreamReader(startPath)){string content = reader.ReadToEnd();writer.Write(content);}}}
}
4.2 解析
4.2.1 整体解析
解压文件同样简单。我们可以使用ZipFile类的ExtractToDirectory方法来解压ZIP文件到指定文件夹:
using System.IO.Compression;string zipPath = @"c:\example\start.zip"; // 要解压的ZIP文件路径
string extractPath = @"c:\example\extract"; // 解压后的文件夹路径ZipFile.ExtractToDirectory(zipPath, extractPath);
这段代码会将start.zip文件解压到extract文件夹中。
4.2.2 单个文件解析
如果你需要更细粒度的控制,比如只解压ZIP文件中的特定文件,你可以使用ZipArchive来实现:
using System.IO;
using System.IO.Compression;string zipPath = @"c:\example\start.zip"; // 要解压的ZIP文件路径
string extractPath = @"c:\example\extract"; // 解压后的文件夹路径
string fileToExtract = "file.txt"; // 要解压的文件名using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{ZipArchiveEntry entry = archive.GetEntry(fileToExtract);if (entry != null){string fullPath = Path.Combine(extractPath, entry.FullName);entry.ExtractToFile(fullPath, overwrite: true);}
}
这段代码会从start.zip文件中解压出file.txt文件到extract文件夹中
4.3 其他
4.3.1 设置压缩级别
在压缩文件时,你可以指定压缩级别来优化压缩效果。ZipArchiveMode.Create方法接受一个CompressionLevel枚举参数,允许你选择不同的压缩级别:
using (FileStream zipToOpen = new FileStream(zipPath, FileMode.Create))
{using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create, true)){// ... 添加文件到ZIP归档中}
}
在这个例子中,第三个参数是布尔值,表示是否压缩归档中的条目。你也可以通过ZipArchiveEntry.CompressionLevel属性为单个条目设置压缩级别。
4.3.2 密码保护
.NET的System.IO.Compression命名空间不支持为ZIP文件添加密码保护。如果你需要这个功能,你可能需要使用第三方库,如DotNetZip
4.3.3 进度反馈
在压缩或解压大文件时,提供进度反馈是一个很好的用户体验。然而,System.IO.Compression命名空间并没有直接提供进度反馈的机制。你可以通过计算处理的文件大小与总大小来估算进度,并使用例如IProgress<T>接口来报告进度。
5、参考资料
这篇文章主要参考了这篇文章:NET环境下使用原生方法实现文件压缩与解压
相关文章:
NET8环境WebAPI实现文件的压缩及下载
目录 1、文件下载的原理2、具体实现2.1 提前准备2.2 服务器端的实现2.3 请求端的实现 3、代码下载4、更多特性4.1 单独压缩文件4.2 解析4.2.1 整体解析4.2.2 单个文件解析 4.3 其他4.3.1 设置压缩级别4.3.2 密码保护4.3.3 进度反馈 5、参考资料 1、文件下载的原理 在实际应用环…...
Ubuntu 18 使用NVIDIA上的HDMI输出声音
前言 在未做修改之前,Settings -> Sound -> Output 里面只有 Digital Output(S/PDIF) - Built-in Audio 不显示HDMI的输出设备检查当前存在的音频设备 sudo lspci -v | grep -A7 -i "audio"输出: 从输出可以看出来是有两个设备的 00:1…...
C#模拟量线性变换小程序
1、一步步建立一个C#项目 一步步建立一个C#项目(连续读取S7-1200PLC数据)_s7协议批量读取-CSDN博客文章浏览阅读1.7k次,点赞2次,收藏4次。本文详细介绍了如何使用C#构建一个项目,通过S7net库连接并连续读取S7-1200 PLC的数据,包括创建窗体应用、配置存储位置、安装S7net库…...
跟《经济学人》学英文:2024年08月10日这期 How AI models are getting smarter
How AI models are getting smarter Deep neural networks are learning diffusion and other tricks 原文: Type in a question to ChatGPT and an answer will materialise. Put a prompt into DALL-E 3 and an image will emerge. Click on TikTok’s “for y…...
Spring Web MVC入门(上)
1. Spring Web MVC Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为“spring MVC”; 什么是Servlet呢? Servlet…...
【c++】公差判断函数 isInTolerance
定义: isInTolerance 函数用来判断一个特定数值(变量)是否在以某个中心值为基准 ,给定半径的范围内。这个函数包含了一个可选的参数 includeEndpoints(默认为 true), 用于决定范围是否包含其端点…...
电脑新加的硬盘如何分区?新加硬盘分区选MBR还是GPT
最近有网友问我,电脑新加的硬盘如何分区?电脑新加的硬盘分区选MBR还是GPT要看引导模式采用uefi还是传统的legacy模式,如果采用的是uefi引导模式,分区类型对应的就是gpt分区(guid),如果引导模式采用的是legacy,对应的分区类型为mb…...
白骑士的Matlab教学基础篇 1.3 控制流
系列目录 上一篇:白骑士的Matlab教学基础篇 1.2 MATLAB基础语法 控制流是编程中的核心概念,通过控制程序执行的顺序,从而实现复杂的逻辑操作。MATLAB 提供了多种控制流语句,包括条件语句、循环语句以及循环控制语句。掌握这些控制…...
设计模式 - 适配器模式
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、适配器…...
docker部署minIO
docker部署minIO 旧版本新版本 旧版本 #-u 以root用户运行容器;--privilegedtrue 给予容器命令访问权限 docker pull minio/minio:RELEASE.2021-06-17T00-10-46Z docker run -p 9001:9000 --name minio -d \-u root --privilegedtrue \-e "MINIO_ROOT_USERmin…...
「Pytorch」BF16 Mixed Precision Training
在深度学习领域,神经网络的训练性能瓶颈常常出现在 GPU显存的使用上。主要表现为两方面: 单卡上可容纳的模型和数据量有限;显存与计算单元之间的带宽和延迟限制了运算速度; 为了解决显卡瓶颈的问题,涌现了不同的解决…...
论文阅读:Efficient Core Maintenance in Large Bipartite Graphs | SIGMOD 2024
还记得我们昨天讨论的《Querying Historical Cohesive Subgraphs over Temporal Bipartite Graphs》这篇论文吗? https://blog.csdn.net/m0_62361730/article/details/141003301 这篇(还没看的快去看) 这篇论文主要研究如何在时间双向图上查询历史凝聚子图,而《E…...
LLMOps — 使用 BentoML 为 Llama-3 模型提供服务
使用 BentoML 和 Runpod 快速设置 LLM API 经常看到数据科学家对 LLM 的开发感兴趣,包括模型架构、训练技术或数据收集。然而,我注意到,很多时候,除了理论方面,许多人在以用户实际使用的方式提供这些模型时遇到了问题…...
微软蓝屏事件揭秘:有问题的数据引发内存读取越界
讲动人的故事,写懂人的代码 CrowdStrike前一阵在官网上发布了上周爆发的全球企业微软蓝屏事件的官方初步复盘结果。其中谈到了这次事件的根本原因: 2024年7月19日,我们部署了两个额外的IPC模板实例。由于内容验证器中的一个bug,使…...
NASA:北极ARCTAS差分吸收激光雷达(DIAL)遥感数据
ARCTAS Differential Absorption Lidar (DIAL) Remotely Sensed Data ARCTAS差分吸收激光雷达(DIAL)遥感数据 简介 ARCTAS差分吸收激光雷达(DIAL)遥感数据是一种远程感测技术,用于测量大气中不同波长的激光辐射被大…...
Android 文件上传与下载
在实际开发涉及文件上传不会自己写上传代码,一般 会集成第三网络库来做图片上传,比如android-async-http,okhttp等,另外还有七牛也提供 了下载和上传的API。 1.项目用到的图片上传的关键方法: 这里用到一个第三方的库…...
Java语言的充电桩系统Charging station system
介绍 SpringBoot 框架,充电桩平台充电桩系统充电平台充电桩互联互通协议云快充协议1.5-1.6协议新能源汽车二轮车公交车二轮车充电-四轮车充电充电源代码充电平台源码Java源码-共享充电桩-充电桩软件 软件介绍 小程序端:城市切换、附近电站、电桩详情页…...
RCE之无参数读取文件
什么是无参数? 顾名思义,就是只使用函数,且函数不能带有参数,这里有种种限制:比如我们选择的函数必须能接受其括号内函数的返回值;使用的函数规定必须参数为空或者为一个参数等 例题: <?…...
Python GUI开发必看:Tkinter Button控件使用详解
Button(按钮)组件用于实现各种各样的按钮。 Button组件可以包含文本或图像,你可以将一个Python的函数或方法与之相关联,当按钮被按下时,对应的函数或方法将被自动执行。 Button组件仅能显示单一字体的文本,…...
上海市计算机学会竞赛平台2024年7月月赛丙组得分排名
题目描述 给定 nn 名学生的考试得分,这些学生的学号为 11 到 nn,其第 ii 号学生的得分为 aiai,请将这些学生按照分数从大到小的顺序排列并输出学号序列。 若两个学生得分相同,则先输出较小的学号。 输入格式 第一行…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
