一、简要介绍
-
字节数组:字节数组是存储数据的字节序列,常用于二进制数据(如图片、音视频、文档等)的表示。
-
文件和字节的关系:文件是由字节构成,字节是文件内容的基本单位。
-
文件以字节形式存储在服务器数据库与文件夹的比较:
存储方式 | 优点 | 缺点 |
---|---|---|
数据库存储 | 便于管理和检索,数据安全性高 | 可能占用更多存储空间,性能较低 |
文件夹存储 | 存储方便,易于访问 | 不便于数据管理和安全控制,缺乏统一性 |
4.字节数组在数据库的存储方式
- SQL Server:VARBINARY(最大2GB)
- MySQL:BLOB(最大64KB)、MEDIUMBLOB(最大16MB)、LONGBLOB(最大 4GB)
5.字节数组在C#的类型
public byte[] FileData { get; set; } //使用byte[]表达字节数组
二、本文数据准备
1.数据表
建表语法示例(sqlserver)
USE [TestABP]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE 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]
GO
SET 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 "文件上传成功!";
}
}