Web开发:ABP框架10——使用数据库存储文件,完成文件的下载和上传
一、简要介绍
-
字节数组:字节数组是存储数据的字节序列,常用于二进制数据(如图片、音视频、文档等)的表示。
-
文件和字节的关系:文件是由字节构成,字节是文件内容的基本单位。
-
文件以字节形式存储在服务器数据库与文件夹的比较:
存储方式 | 优点 | 缺点 |
---|---|---|
数据库存储 | 便于管理和检索,数据安全性高 | 可能占用更多存储空间,性能较低 |
文件夹存储 | 存储方便,易于访问 | 不便于数据管理和安全控制,缺乏统一性 |
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 "文件上传成功!";}
}