相关知识:

  1. 在SQL Server中,一般情况下,每行数据的总长度不能超过8K字节。因此,下列数据类型的长度,也不能超过8K字节:binary,char(),nchar(),varchar(),nvarchar()。注意,由于nvarchar是Unicode字符,因此,其最大长度也不能超过nvarchar(4000)
  2. 对于超长数据,尤其是二进制数据(例如音频视频数据等),SQL Server提供了下列数据类型(可以超过8K):image,varbinary(max),text,ntext,varchar(max),nvarchar(max)
  3. 对于较小的二进制数据,可以公国DataReader或者DataSet一次性读取。但是对于较大的二进制数据(BLOB),例如1MB以上,如果一次性把所有数据都读取出来,就会消耗大量的程序内存(字节数组)。因此,往往是采用分批读取的方式进行
  4. SqlDataReader的二进制读取:
    • 在ExecuteReader调用时,要指定CommandBehavior.SequentialAccess选项,以表明通过顺序的方式逐段读取

       SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
    • GetBytes函数,可以将二进制字段中的数据逐段读到缓冲区中
    • 应当优先把BLOB字段前的其他字段读取出来,否则一旦开始读BLOB字段,将无法再回头去读之前的字段

代码示例:

  • 数据库:采用红皮书的示例数据库,AdventureWorks_WroxSSRS2012,使用Production.ProductPhoto表,获取其中的图片数据信息

   

  • 引入:

    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
  • 基本定义:

             const int BUF_SIZE = ;//缓冲区大小
    static string strConn = @"server=Joe-PC;database=AdventureWorks_WroxSSRS2012;uid=sa;pwd=root";
    static SqlConnection conn = new SqlConnection(strConn);
    //优先把BLOB字段前的其他字段读取出来,否则一旦开始读BLOB字段,将无法再回头去读之前的字段(注意此sql语句中字段的顺序与数据库字段顺序的对比)
    static string strCmd = "SELECT ProductPhotoID,ThumbnailPhotoFileName,ThumbNailPhoto,LargePhotoFileName,LargePhoto FROM Production.ProductPhoto";
    static SqlCommand cmd = new SqlCommand(strCmd, conn);
  • 访问ProductPhoto表
             static void Main(string[] args)
    {
    try
    {
    conn.Open();
    //以SequentialAccesss方式打开DataReader
    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
    while (dr.Read())
    {
    int productPhotoID = dr.GetInt32();
    string thumbnailPhotoFileName = dr.GetString();//读取缩略图文件名
    WriteThumbnailPhotoFile(thumbnailPhotoFileName, dr);//将缩略图二进制数据写入磁盘文件
    string largePhotoFileName = dr.GetString();//读取大图文件名
    WriteLargePhotoFile(largePhotoFileName, dr);//将大图二进制数据写入磁盘文件
    }
    }
    catch (Exception e)
    {
    Console.WriteLine(e);
    }
    finally
    {
    conn.Close();
    }
    }
  • 将缩略图二进制数据写入磁盘文件的函数
             static void WriteThumbnailPhotoFile(string fileName, SqlDataReader dr)
    {
    string path = "..\\..\\images\\Thumbnail\\" + fileName;//需要预先在项目文件夹中建立此目录
    FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
    //ThumbnailPhoto的数据比较小(没有超过8KB),因此选择一次性读出,直接写入文件
    byte[] buf = dr[] as byte[];
    fs.Write(buf, , buf.Length);
    fs.Close();
    }
  • 将大图二进制数据写入磁盘文件的函数
             static void WriteLargePhotoFile(string fileName, SqlDataReader dr)
    {
    string path = "..\\..\\images\\Large\\" + fileName;//需要预先在项目文件夹中建立此目录
    FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
    byte[] buf = new byte[BUF_SIZE];
    long bytesRead = ;
    long startIndex = ;
    //LargePhoto的数据比较大,因此分批次读出,分别写入文件
    while ((bytesRead = dr.GetBytes(, startIndex, buf, , BUF_SIZE)) > )
    {
    fs.Write(buf, , (int)bytesRead);
    startIndex += bytesRead;
    }
    fs.Close();
    }

程序说明:

需要预先在本项目文件夹下建立images目录,内有thumbnail和large子目录,用于存放从数据库获取的图片

ADO.NET笔记——读取二进制大对象(BLOB)的更多相关文章

  1. ADO.NET笔记——存储二进制大对象(BLOB)

    相关知识 上传二进制大对象(Binary Large Object)(如图片.视频等)的基本编程步骤是: 在数据库中使用varbinary(MAX).varchar(MAX)或者nvarchar(MA ...

  2. ADO学习笔记之注入漏洞与参数化查询

    ADO学习笔记之注入漏洞与参数化查询 作为新手,在学习ADO程序时,使用 sql 语言查询数据时,很容易写类似如下代码: using (SqlConnection con = new SqlConne ...

  3. ADO.NET笔记20160322

    ####ADO.NET ####1 启用sa验证与窗体相关知识     - 启用sa验证     - ShowDialog() ---- ####2 连接字符串     Data Source=服务器 ...

  4. ADO.net笔记

    1.DbConnectionConnection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接.所有Connection对象的基类都是DbConnection类.Conn ...

  5. 10.4(java学习笔记)CLOB,BLOB基本操作

    一.CLOB 1.1CLOB简介 CLOB全称是(Character Large Object)字符大对象,用于存储大量的文本数据. 字符大对象的操作不同于一般数据,是通过流来完成的. 1.2MySQ ...

  6. ADO.NET(OleDb)读取Excel表格时的一个BUG

    如果我们有例如以下一个Excel表格:    如今要使用C#程序读取其内容: using System;  using System.Data.OleDb;    namespace Skyiv.Be ...

  7. python3笔记-读取ini配置文件

    在代码中经常会通过ini文件来配置一些常修改的配置.下面通过一个实例来看下如何写入.读取ini配置文件. 需要的配置文件是: [path] back_dir = /Users/abc/PycharmP ...

  8. Ado.net 数据库读取文件

    string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; using ...

  9. FPGA笔记-读取.dat文件

    读取.dat图像文件 .dat文件是matlab生成的图像文件 initial begin // Initialize Inputs CLK = 0; RST = 1; IMAGE_DATA = 0; ...

随机推荐

  1. 查看Linux系统架构类型的5条常用命令

    导读 很多时候我们都需要查看当前 Linux 系统是 32 位还是 64 位系统架构类型,本文中我将向大家推荐 5 条常用命令.无论你使用的是桌面版或是只装了文本界面的 Linux 环境,以下命令几乎 ...

  2. Linux中命令链接操作符的十个最佳实例

    转载: http://www.linuxeden.com/html/softuse/20140112/147406.html http://www.tecmint.com/chaining-opera ...

  3. tachyon 初识

    一.简介 Tachyon是一个高容错的分布式文件系统,允许文件以内存的速度在集群框架中进行可靠的共享,就像Spark和MapReduce那样.通过利用信息继承,内存侵入,Tachyon获得了高性能.T ...

  4. 基于C#实现的HOOK键盘钩子实例代码

    本文所述为基于C#实现的HOOK实例,该实例可用来屏蔽系统热键.程序主要实现了安装钩子.传递钩子.卸载钩子等功能.在传递钩子中:<param name="pHookHandle&quo ...

  5. IOS 如何成为开发者&购买开发者账号 感想

    1.申请apple id  要注意 选择你在的国家 比如 China就会在右下角的页面出校圆圈的中国国旗,不然他们会说“无法接收你的请求”.我苦恼了半天,最后我重新申请apple ID 操作的,因为 ...

  6. 数据结构【一】:简单队列simple queue

    简单的FIFO队列实现,非线程安全! 1.queue.h : abstract data type queue #ifndef CUR_QUEUE_H #define CUR_QUEUE_H #inc ...

  7. 【JEMTER】后置处理器JSON Path Extractor获取server端返回的json中某项值

    需求1:点击所有报表模板时,server端返回所有报表模板的ID(templateId),测试时需要下载某个模板生成的报表 需求2:点击单个报表模板时,server端返回这个报表模板下的所有报表ID( ...

  8. viewflipper动画切换屏幕

    整个项目的 package com.example.viewflipper; import android.R.integer; import android.app.Activity; import ...

  9. Android开发——实现固定在ScrollView顶部的View,类似于新浪微博的评论列表的顶部

    现在很多App都实现了这个功能,例如新浪微博评论页面的评论.转发.赞的数字可以固定在屏幕上方.我个人很喜欢这种设计,所以利用一点空余时间简单实现了一个类似的功能. 先来看一下上面这张图的效果 这个是新 ...

  10. iOS webview加载html自定义选项框选词

    项目要求:webview加载html网址,内容为英文文本,需要获取文本上的单词 这个是最终效果图: 思路是先实现自定义的选项框(不带系统选项)再获取到滑选的单词: 实现的步骤: 首先是替换掉系统长按出 ...