当前位置: 首页 > news >正文

Web开发:ABP框架10——使用数据库存储文件,完成文件的下载和上传

一、简要介绍

  1. 字节数组:字节数组是存储数据的字节序列,常用于二进制数据(如图片、音视频、文档等)的表示。

  2. 文件和字节的关系:文件是由字节构成,字节是文件内容的基本单位。

  3. 文件以字节形式存储在服务器数据库与文件夹的比较

存储方式优点缺点
数据库存储便于管理和检索,数据安全性高可能占用更多存储空间,性能较低
文件夹存储存储方便,易于访问不便于数据管理和安全控制,缺乏统一性

        4.字节数组在数据库的存储方式 

  • SQL Server:VARBINARY(最大2GB)
  • MySQL:BLOB(最大64KB)、MEDIUMBLOB(最大16MB)、LONGBLOB(最大 4GB)

        5.字节数组在C#的类型

public byte[] FileData { get; set; }  //使用byte[]表达字节数组

二、本文数据准备

1.数据表

建表语法示例(sqlserver)

USE [TestABP]
GOSET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GOSET ANSI_PADDING ON
GOCREATE TABLE [dbo].[Files]([Id] [int] IDENTITY(1,1) NOT NULL,[FileName] [nvarchar](255) NULL,[FileData] [varbinary](max) NULL, -- 使用varbinary表达字节数组
PRIMARY KEY CLUSTERED 
([Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GOSET ANSI_PADDING OFF
GO

2.本文实体

本文采用的ORM框架是:freesql

[Table("Files")]
public class Files  
{[FreeSql.DataAnnotations.Column(IsPrimary = true,IsIdentity = true,Name ="Id")]public int Id { get; set; }[Column("FileName")]public string FileName { get; set; }[Column("FileData")]public int? FileData { get; set; }}

三、【Demo】文件下载

/// <summary>
/// 下载文件
/// </summary>
/// <returns></returns>
[Route("DownLoadFile")]
[HttpGet]
public async Task DownLoadFile()
{//通过查库获取字节形式的文件byte[] file = _freeSql.Select<Files>().Where(x => x.Id == 1).ToOne()?.FileData;// 检查文件是否存在if (file != null){var context = _httpContextAccessor.HttpContext;var response = context.Response;response.Clear();response.Headers.Add("Content-Disposition", $"attachment; filename=Demo.xls");// 设置响应头:指定下载的文件名response.ContentType = "application/octet-stream"; // 指定为MIME类型,浏览器根据扩展名自动识别响应编辑器打开response.Body.WriteAsync(file, 0, file.Length).Wait();//写入响应流}else{throw new FileNotFoundException("文件未找到");}}

 

【中文乱码问题】

设置MIME类型时,声明utf-8 字符集,并且用WebUtility.UrlEncode处理中文字符。

response.Headers.Add("Content-Disposition", $"attachment;filename*=utf-8''{WebUtility.UrlEncode("123下载.xlsx")}");

四、【Demo】文件上传

/// <summary>
/// 上传文件
/// </summary>
/// <returns></returns>
[Route("UploadFile")]
[HttpPost]
public async Task<string> UploadFile(IFormFile file)
{if (file == null || file.Length == 0){throw new FileNotFoundException("未选择文件上传.");}// 读取文件的内容using (var memoryStream = new MemoryStream()){await file.CopyToAsync(memoryStream);var fileData = memoryStream.ToArray();// 将文件存储到数据库中var fileRecord = new Files{FileData = fileData,FileName = file.FileName, // 可以存储文件名或其他相关信息};// 使用FreeSQL插入数据await _freeSql.Insert(fileRecord).ExecuteAffrowsAsync();return "文件上传成功!";}
}

http://www.xdnf.cn/news/65701.html

相关文章:

  • 【第四章】19-匹配规则定义
  • GPT-4.1 开启智能时代新纪元
  • 算法之动态规划
  • 第42讲:走进智慧农业的“感知神经系统”——农田遥感 + 边缘计算的融合实践
  • WiFi模块使用AT+lwip上网
  • 苹果开发者账号 3.2(f) 被封排查思路及重生指南
  • 在 Spring Boot 项目中怎么识别和优化慢 SQL ?
  • 每日一题——数据中心网络地址规划
  • 简易版自制RTOS
  • AI律师匹配AI分析法律需求意图并匹配律师
  • 7. 服务通信 ---- 使用自定义srv,服务方和客户方cpp,python文件编写
  • 操作指南:在vue-fastapi-admin上增加新的功能模块
  • 江湖密码术:Rust中的 bcrypt 加密秘籍
  • 算法 | 成长优化算法(Growth Optimizer,GO)原理,公式,应用,算法改进研究综述,matlab代码
  • QLisview 实现model deletage,并且在不需要编辑的情况下自定义UI
  • 【Redis】Jedis与Jedis连接池
  • Oracle数据库和PLSQL安装配置
  • 基于单片机的BMS热管理功能设计
  • 实验四 Java图形界面与事件处理
  • 如何对只能有一个`public`顶层类这句话的理解
  • 【解决】Vue + Vite + TS 配置路径别名成功仍爆红
  • Unreal Engine中FRotator与FQuat在赛车游戏方向盘控制中的协同应用解析
  • 【C++编程入门】:从零开始掌握基础语法
  • CENTOS 7 安装VNC
  • 【Java面试笔记:基础】1.谈谈你对Java平台的理解?
  • 移动端动态滑动拨盘选择器【Axure元件库】
  • 自注意力机制、多头自注意力机制、填充掩码 Python实现
  • 如何在白平衡标定种构建不同类型的白平衡色温坐标系
  • Android 音悦适配-v4.3.3-可在线播放可下载音乐的第三方APP
  • 【解决方法】关于解决QGC地面站4.4.3中文BUG,无法标注航点的问题