You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中通过存储过程读取SQL Server存储的字节数组格式图片

从SqlDataReader读取可变长度二进制图片数据的实现

你不需要手动实现复杂的分块读取逻辑,以下两种经过验证的写法都可以正确读取任意长度的图片字节数组,适配SQL Server的varbinary(MAX)等二进制字段类型。


方法1:直接强转读取(推荐,代码最简洁)

ADO.NET 读取二进制列时,索引器会自动返回完整的byte[]类型结果,你只需要提前判断字段是否为DBNull即可,不需要手动处理字节长度,性能和手动调用GetBytes没有本质区别,是业务开发中最常用的写法:

// OverViewImage是返回结果的第5列,索引从0开始即序号为4
byte[]? overViewImage = null;
int imageColumnIndex = 4;
if (!reader.IsDBNull(imageColumnIndex))
{
    overViewImage = (byte[])reader[imageColumnIndex];
}

如果担心列序号和存储过程返回顺序不匹配,也可以用列名读取,写法容错性更高,性能损耗可以忽略:

int imgColIdx = reader.GetOrdinal("OverViewImage");
if (!reader.IsDBNull(imgColIdx))
{
    overViewImage = (byte[])reader[imgColIdx];
}

方法2:使用GetBytes方法手动读取

如果你明确要使用GetBytesAPI实现读取,可以先通过一次空缓冲区调用拿到字段的总字节长度,再初始化对应长度的数组完成一次性读取,适合对读取过程有自定义需求的场景:

byte[]? overViewImage = null;
int imageColumnIndex = 4;
if (!reader.IsDBNull(imageColumnIndex))
{
    // 传入null作为缓冲区,方法返回值就是该字段存储的总字节长度
    long totalByteLength = reader.GetBytes(imageColumnIndex, 0, null, 0, 0);
    // 初始化和实际存储长度一致的字节数组
    overViewImage = new byte[totalByteLength];
    // 读取全部字节到数组中
    reader.GetBytes(imageColumnIndex, 0, overViewImage, 0, (int)totalByteLength);
}

如果存储的是单文件大小超过100MB的超大二进制数据,可以把缓冲区设置为固定大小(如8KB),循环调用GetBytes分块写入MemoryStream,避免一次性占用过多内存。车牌识别的抓拍图片通常体积在几MB以内,一次性读取即可。


完整循环赋值示例

替换你现有代码中while循环内的逻辑即可:

while (reader.Read())
{
    var entryDateTime = reader.GetDateTime(0);
    var plate = reader.GetString(1);
    var plaza = reader.GetString(2);
    var direction = reader.GetString(3);
    
    byte[]? overViewImage = null;
    int imgColIdx = 4;
    if (!reader.IsDBNull(imgColIdx))
    {
        overViewImage = (byte[])reader[imgColIdx];
    }

    var xList = new PlateNumberEntity
    {
        EntryDateTime = entryDateTime,
        PlateNumber = plate,
        Plaza = plaza,
        Direction = direction,
        OverViewImage = overViewImage
    };
    list.Add(xList);
}

注意事项

  • 必须提前通过IsDBNull判断字段值是否为空,否则数据库中存储NULL值时会触发类型转换异常
  • 确保列序号和存储过程GetAlprEntryInfo返回的字段顺序完全一致,用列名+GetOrdinal的写法可以避免存储过程字段顺序调整导致的取值错误

内容的提问来源于stack exchange,提问作者Ibanez1408

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 09:06:51