C#如何通过流操作MySQL/MariaDB的BLOB(LONGBLOB)数据?
优化LONGBLOB数据的流操作方案
针对你的需求,确实可以通过流的方式来读写LONGBLOB数据,避免一次性将整个文件加载到内存中,以下是具体实现方案:
一、流方式插入数据
使用FileStream结合MySQL参数的流赋值能力,让驱动分块传输数据,而非一次性读取全部文件内容到内存。
using (var connection = new MySqlConnection(connectionString)) { string query = "INSERT INTO files(name, uploader, bin) VALUES (@fileName, @uploader, @bin)"; using (var command = connection.CreateCommand()) { command.CommandText = query; command.Parameters.AddWithValue("@fileName", Path.GetFileName(filePath)); command.Parameters.AddWithValue("@uploader", "John Doe"); // 以只读模式打开文件流,直接作为参数值传入 using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var blobParam = new MySqlParameter("@bin", MySqlDbType.LongBlob); blobParam.Value = fileStream; command.Parameters.Add(blobParam); connection.Open(); command.ExecuteNonQuery(); } } }
核心优化点:
- 直接传递
FileStream而非byte[],MySQL驱动会自动处理流的分块传输,无需手动拆分文件 - 用
using包裹流对象,确保文件和数据库资源被正确释放 - 明确指定
MySqlDbType.LongBlob参数类型,避免驱动自动推断可能引发的异常
二、流方式读取数据
读取LONGBLOB时,通过流的方式将数据写入本地文件,避免一次性加载整个大对象到内存:
using (var connection = new MySqlConnection(connectionString)) { string query = "SELECT bin FROM files WHERE name = @fileName"; using (var command = connection.CreateCommand()) { command.CommandText = query; command.Parameters.AddWithValue("@fileName", targetFileName); connection.Open(); using (var reader = command.ExecuteReader()) { if (reader.Read()) { // 获取LONGBLOB对应的流对象 using (var blobStream = reader.GetStream(0)) // 创建本地文件流,将数据库流数据写入文件 using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write)) { // 自动分块复制流,默认缓冲区大小81920字节,可按需调整 blobStream.CopyTo(fileStream); } } } } }
核心优化点:
- 使用
MySqlDataReader.GetStream()直接获取流,替代GetBytes()的手动分块逻辑 - 借助
Stream.CopyTo()完成高效的分块数据复制,大幅简化代码同时降低内存占用 - 全程用
using管理流对象,避免资源泄漏
内容的提问来源于stack exchange,提问作者OlimexSmart
相关产品推荐
相关产品推荐

