http://expert.csdn.net/Expert/TopicView3.asp?id=1424660

解决方案 »

  1.   

    从数据库中获取 BLOB 值DataReader 的默认行为是在整个数据行可用时立即以行的形式加载传入数据。但是,对于二进制大对象 (BLOB) 则需要进行不同的处理,因为它们可能包含数十亿字节的数据,而单个行中无法包含如此多的数据。Command.ExecuteReader 方法具有一个重载,它将采用 CommandBehavior 参数来修改 DataReader 的默认行为。您可以将 CommandBehavior.SequentialAccess 传递到 ExecuteReader 方法来修改 DataReader 的默认行为,以便让 DataReader 按照顺序在接收到数据时立即将其加载,而不是加载数据行。这是加载 BLOB 或其他大数据结构的理想方案。在将 DataReader 设置为使用 SequentialAccess 时,务必要注意访问所返回字段的顺序。DataReader 的默认行为是在整个行可用时立即加载该行,这使您能够在读取下一行之前按任何顺序访问所返回的字段。但是,当使用 SequentialAccess 时,必须按顺序访问由 DataReader 返回的不同字段。例如,如果查询返回三个列,其中第三列是 BLOB,则必须在访问第三个字段中的 BLOB 数据之前返回第一个和第二个字段的值。如果在访问第一个或第二个字段之前访问第三个字段,则第一个和第二个字段值将不再可用。这是因为 SequentialAccess 已修改 DataReader,使其按顺序返回数据,当 DataReader 已经读取超过特定数据时,该数据将不可用。当访问 BLOB 字段中的数据时,请使用 DataReader 的 GetBytes 类型化访问器,该访问器将使用二进制数据填充 byte 数组。您可以指定要返回的特定数据缓冲区大小以及从返回的数据中读取的第一个字节的起始位置。GetBytes 将返回 long 值,它表示所返回的字节数。如果向 GetBytes 传递空的 byte 数组,所返回的长值将是 BLOB 中字节的总数。您可以选择将字节数组中的某索引指定为所读取数据的起始位置。以下示例从 Microsoft SQL Server 中的 pubs 示例数据库中返回发行者 ID 和徽标。发行者 ID (pub_id) 是字符字段,而徽标则是图形,即 BLOB。请注意,由于必须按顺序访问字段,所以将在访问徽标之前访问当前数据行的发行者 ID。
    SqlConnection pubsConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;");
    SqlCommand logoCMD = new SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn);FileStream fs;                          // Writes the BLOB to a file (*.bmp).
    BinaryWriter bw;                        // Streams the BLOB to the FileStream object.int bufferSize = 100;                   // Size of the BLOB buffer.
    byte[] outbyte = new byte[bufferSize];  // The BLOB byte[] buffer to be filled by GetBytes.
    long retval;                            // The bytes returned from GetBytes.
    long startIndex = 0;                    // The starting position in the BLOB output.string pub_id = "";                     // The publisher id to use in the file name.// Open the connection and read data into the DataReader.
    pubsConn.Open();
    SqlDataReader myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess);while (myReader.Read())
    {
      // Get the publisher id, which must occur before getting the logo.
      pub_id = myReader.GetString(0);    // Create a file to hold the output.
      fs = new FileStream("logo" + pub_id + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
      bw = new BinaryWriter(fs);  // Reset the starting byte for the new BLOB.
      startIndex = 0;  // Read the bytes into outbyte[] and retain the number of bytes returned.
      retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);  // Continue reading and writing while there are bytes beyond the size of the buffer.
      while (retval == bufferSize)
      {
        bw.Write(outbyte);
        bw.Flush();    // Reposition the start index to the end of the last buffer and fill the buffer.
        startIndex+= bufferSize;
        retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
      }  // Write the remaining buffer.
      bw.Write(outbyte);
      bw.Flush();  // Close the output file.
      bw.Close();
      fs.Close();
    }// Close the reader and the connection.
    myReader.Close();
    pubsConn.Close();
      

  2.   

    //简介:数据库中图片存蓄及读取
         //作者:engine
         /*
         说明:在ASP中,我们用Request.TotalBytes、Request.BinaryRead()来上传图片,这个可恶的BinaryRead()方法非常笨,单个文件上传倒没什么大事,单如果多个图片上专可就花大气力了…!而现在ASP.Net中将会把解决以前ASP中文件上传的种种问题,使你在ASP.Net中轻轻松松开发出功能强大的上传程序,下面大家看看例子啦。
         */
         //注意:由于作者水平有限,错误是难免的,如发现错误请指教
         //Email:[email protected] 
         
         /*
         首先在SQL Server中建立一个图片存储的数库表,ImageData Column为图象二进制数据储存字段,ImageContentType Column为图象文件类型记录字段,ImageDescription Column为储蓄图象文件说明字段,ImageSize Column为储存图象文件长度字段,结构如下:
         CREATE TABLE [dbo].[ImageStore] (
         [ImageID] [int] IDENTITY (1, 1) NOT NULL ,
         [ImageData] [image] NULL , 
         [ImageContentType] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
         [ImageDescription] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL ,
         [ImageSize] [int] NULL 
         ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
         */ 
         
         //UpLoadImage.aspx程序内容如下:
         <%@ Page Inherits="UploadImage.UploadImage" SRC="UpLoadImage.cs" Language="C#"%>
         <HTML><title>上传图片</title>
         <BODY bgcolor="#FFFFFF">
         <FORM ENCTYPE="multipart/form-data" RUNAT="server" ID="Form1">
         <TABLE RUNAT="server" WIDTH="700" ALIGN="left" ID="Table1" cellpadding="0" cellspacing="0" border="0">
         <TR>
         <TD>上传图片(选择你要上传的图片)</TD>
         <TD>
         <INPUT TYPE="file" ID="UP_FILE" RUNAT="server" STYLE="Width:320" ACCEPT="text/*" NAME="UP_FILE">
         </TD>
         </TR>
         <TR>
         <TD> 
         文件说明(添加上传图片说明,如:作者、出处)
         </TD>
         <TD>
         <asp:TextBox RUNAT="server" WIDTH="239" ID="txtDescription" MAINTAINSTATE="false" />
         </TD>
         </TR>
         <TR>
         <TD>
         <asp:Label RUNAT="server" ID="txtMessage" FORECOLOR="red" MAINTAINSTATE="false" />
         </TD>
         <TD>
         <asp:Button RUNAT="server" WIDTH="239" ONCLICK="Button_Submit" TEXT="Upload Image" />
         </TD>
         </TR>
         </TABLE>
         </FORM>
         </BODY>
         </HTML>
         //-------------------------------------------------------------------
         //UpLoadImage.cs程序内容如下:
         using System;
         using System.Web;
         using System.IO;
         using System.Data;
         using System.Data.SqlClient;
         using System.Web.UI;
         using System.Web.UI.WebControls;
         using System.Web.UI.HtmlControls; 
         namespace UploadImage
         { 
         public class UploadImage : Page { 
         protected HtmlInputFile UP_FILE; //HtmlControl、WebControls控件对象
         protected TextBox txtDescription;
         protected Label txtMessage;
         protected Int32 FileLength = 0; //记录文件长度变量 
         protected void Button_Submit(System.Object sender, System.EventArgs e) {
         HttpPostedFile UpFile = UP_FILE.PostedFile; //HttpPostedFile对象,用于读取图象文件属性
         FileLength = UpFile.ContentLength; //记录文件长度 
         try {
         if (FileLength == 0) { //文件长度为零时
         txtMessage.Text = "<b>请你选择你要上传的文件</b>"; 
         } else {
         Byte[] FileByteArray = new Byte[FileLength]; //图象文件临时储存Byte数组
         Stream StreamObject = UpFile.InputStream; //建立数据流对像
         //读取图象文件数据,FileByteArray为数据储存体,0为数据指针位置、FileLnegth为数据长度
         StreamObject.Read(FileByteArray,0,FileLength); 
         //建立SQL Server链接
         SqlConnection Con = new SqlConnection("Data Source=Localhost;Initial Catalog=testdb;User ID=sa;Pwd=;");
         String SqlCmd = "INSERT INTO ImageStore (ImageData, ImageContentType, ImageDescription, ImageSize) VALUES (@Image, @ContentType, @ImageDescription, @ImageSize)";
         SqlCommand CmdObj = new SqlCommand(SqlCmd, Con);
         CmdObj.Parameters.Add("@Image",SqlDbType.Binary, FileLength).Value = FileByteArray;
         CmdObj.Parameters.Add("@ContentType", SqlDbType.VarChar,50).Value = UpFile.ContentType; //记录文件类型
         //把其它单表数据记录上传
         CmdObj.Parameters.Add("@ImageDescription", SqlDbType.VarChar,200).Value = txtDescription.Text;
         //记录文件长度,读取时使用
         CmdObj.Parameters.Add("@ImageSize", SqlDbType.BigInt,8).Value = UpFile.ContentLength;
         Con.Open();
         CmdObj.ExecuteNonQuery(); 
         Con.Close();
         txtMessage.Text = "<p><b>OK!你已经成功上传你的图片</b>";//提示上传成功
         }
         } catch (Exception ex) {
         txtMessage.Text = ex.Message.ToString();
         }}}}
         //----------------------------------------------------------------------
         //好了,图片已经上传到数据库,现在还要干什么呢?当然是在数据库中读取及显示在Web页中啦,请看以下程序:
         //ReadImage.aspx程序内容如下:
         /----------------------------------------------------------------------- 
         <%@ Page Inherits="ReadImage.MainDisplay" SRC="ReadImage.cs"%> 
         //----------------------------------------------------------------------
         //ReadImage.cs程序内容如下:
         using System;
         using System.Data;
         using System.Data.SqlClient;
         using System.Web.UI;
         using System.Web.UI.WebControls;
         using System.Web.UI.HtmlControls;
         namespace ReadImage {
         public class MainDisplay : System.Web.UI.Page {
         public void Page_Load(System.Object sender, System.EventArgs e) {
         int ImgID = Convert.ToInt32(Request.QueryString["ImgID"]); //ImgID为图片ID 
         //建立数据库链接
         SqlConnection Con = new SqlConnection("Data Source=KING;Initial Catalog=testdb;User ID=sa;Pwd=;");
         String SqlCmd = "SELECT * FROM ImageStore WHERE ImageID = @ImageID";
         SqlCommand CmdObj = new SqlCommand(SqlCmd, Con);
         CmdObj.Parameters.Add("@ImageID", SqlDbType.Int).Value = ImgID;
         Con.Open();
         SqlDataReader SqlReader = CmdObj.ExecuteReader();
         SqlReader.Read(); 
         Response.ContentType = (string)SqlReader["ImageContentType"];//设定输出文件类型
         //输出图象文件二进制数制
         Response.OutputStream.Write((byte[])SqlReader["ImageData"], 0, (int)SqlReader["ImageSize"]); 
         Response.End();
         Con.Close();
         //很简单吧^_^
         }
         }
         }
         //--------------------------------------------------------------------
         //最后,我们当然要把它在Web页面显示出来啦
         //ShowImage.hml
         <html>
         <body>
         这个是从数据库读取出来的图象:<img src="ReadImage.aspx?ImgID=1">
         <body>
         </html>