asp.net(C#)从数据库中获取 BLOB 值,生成xml文件

本文介绍如何使用CommandBehavior.SequentialAccess处理大型二进制对象(BLOB),并提供了从Oracle数据库读取XML文件的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://hi.baidu.com/net1979/blog/item/e050632a0cb6899f023bf661.html

默认情况下,DataReader 在整个数据行可用时立即以行的形式加载传入数据。但是,对于二进制大对象 (BLOB) 则需要进行不同的处理,因为它们可能包含数十亿字节的数据,而单个行中无法包含如此多的数据。Command.ExecuteReader 方法具有一个重载,它将采用 CommandBehavior 参数来修改 DataReader 的默认行为。您可以将 SequentialAccess 传递到 ExecuteReader 方法来修改 DataReader 的默认行为,使其按照顺序在接收到数据时立即将其加载,而不是加载数据行。这是加载 BLOB 或其他大数据结构的理想方案。请注意,该行为可能会因数据源的不同而不同。例如,从 Microsoft Access 中返回 BLOB 会将整个 BLOB 加载到内存中,而不是按照顺序在接收到数据时立即将其加载。

在将 DataReader 设置为使用 SequentialAccess 时,务必要注意访问所返回字段的顺序。DataReader 的默认行为是在整个行可用时立即加载该行,这样可以在读取下一行之前按任何顺序访问所返回的字段。但是,当使用 SequentialAccess 时,必须按顺序访问由 DataReader 返回的字段。例如,如果查询返回三个列,其中第三列是 BLOB,则必须在访问第三个字段中的 BLOB 数据之前返回第一个和第二个字段的值。如果在访问第一个或第二个字段之前访问第三个字段,则第一个和第二个字段值将不再可用。这是因为 SequentialAccess 已修改 DataReader,使其按顺序返回数据,当 DataReader 已经读取超过特定数据时,该数据将不可用。

在访问 BLOB 字段中的数据时,请使用 DataReader 的 GetBytes 或 GetChars 类型化访问器,它们将用数据来填充数组。还可以对字符数据使用 GetString;但是为了节省系统资源,您可能不希望将整个 BLOB 值加载到单个字符串变量中。您可以指定要返回的特定数据缓冲区大小,以及从返回的数据中读取的第一个字节或字符的起始位置。GetBytes 和 GetChars 将返回一个 long 值,它表示返回的字节或字符数。如果将一个空数组传递给 GetBytes 或 GetChars,则返回的长值将是 BLOB 中字节或字符的总数。您可以选择将数组中的某个索引指定为所读取数据的起始位置。

上面的内容为asp.net帮助中的信息,还是用自已的例子来说明吧,使用数据库为oracle9i:

protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["processinstId"] != null && Request.QueryString["processinstId"] != "")
        {
            string processinstId = Request.QueryString["processinstId"];
            setxmldoc(processinstId);
        }
       
    }

/// <summary>
    /// 从数据库中取xml,生成名为processinstld的文件,blob中原来存的文件就是xml文件,只是把它取出来而已,下一次要写一个把xml文件写入到blob中的例子
    /// </summary>
    /// <param name="processinstId">编号ID</param>

//例一:将文件取出后保存在服务器上
    private void setxmldoc(string processinstId)
    {
        string getsqL = "select processinst_id, xmlconf from uwf_processinstance where processinst_id='" + processinstId + "'";
        OracleConnection connection = GenericClassOra.connect();
        OracleCommand command = new OracleCommand(getsqL, connection);
        //文件位置
        string filePath = Server.MapPath(processinstId + ".xml");
        // 取出后写到一个文件中
        FileStream stream;
        // 以二进制形式将基元类型写入流.
        BinaryWriter writer;

        int bufferSize = 1024;
        // 该字节的BLOB缓冲区,以填补getbytes
        byte[] outByte = new byte[bufferSize];
        long retval;
        long startIndex = 0;
        string pubID = "";

        connection.Open();
        OracleDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

        while (reader.Read())
        {
            //读数据
            pubID = reader.GetString(0);

            //创建一个文件.
            stream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            writer = new BinaryWriter(stream);
            // 重置.
            startIndex = 0;
            //
            retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);

            while (retval == bufferSize)
            {
                writer.Write(outByte);
                writer.Flush();

                startIndex += bufferSize;
                retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
            }
            //
            writer.Write(outByte, 0, (int)retval);
            writer.Flush();

            //释放资源
            writer.Close();
            stream.Close();
        }

        // 关闭连接
        reader.Close();
        connection.Close();

        //到这就算是结束的,可是为了看生成的xml正确不正确,要把它显示到网页上,下面的你可以不要

        XmlDocument xmldoc = new XmlDocument();
        Response.ContentEncoding = System.Text.Encoding.Default;
        Response.ContentType = "text/xml ";
        //取xml
        xmldoc.Load(filePath);
        //打开xml试试
        Response.Write(xmldoc.OuterXml);
    }

例二:将文件取出后输出到页面上

private void setxmldocbyte(string processinstId)
    {
        string getsqL = "select xmlconf from uwf_processinstance where processinst_id='" + processinstId + "'";
        OracleConnection connection = GenericClassOra.connect();
        OracleCommand command = new OracleCommand(getsqL, connection);
        try
        {                  
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

            while (reader.Read())
            {
                OracleLob myLob = reader.GetOracleLob(0);
                //长度是long,转为int32  
                int myLength = Convert.ToInt32(myLob.Length);
                Byte[] Buffer = new byte[myLength];
                myLob.Read(Buffer, 0, myLength);

                this.Response.Clear();
                //输出mime类型,根据上传的文件取到的mimetype  
                this.Response.ContentType = "xml";
                this.Response.BinaryWrite(Buffer);
                this.Response.End();
                //释放资源               
            }

            // 关闭连接
            reader.Close();
            connection.Close();
        }
        catch(Exception e)
        {
            throw e;
        }
        finally
        {
            if(connection.State==ConnectionState.Open)
                connection.Close();
        }
    }

方法三:常用,取出以后直接在客户端页面上输出

    /// <summary>
    /// 从数据库中取xml
    /// </summary>
    /// <param name="processinstId">ID</param>
    private void setxmldoc(string processinstId)
    {
        string getsqL = "select xmlconf from uwf_processinstance where processinst_id='" + processinstId + "'";
        OracleConnection connection = GenericClassOra.connect();
        OracleCommand command = new OracleCommand(getsqL, connection);
        try
        {
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);

            while (reader.Read())
            {
                OracleLob myLob = reader.GetOracleLob(0);
                //长度是long,转为int32  
                int myLength = Convert.ToInt32(myLob.Length);
                Byte[] Buffer = new byte[myLength];
                myLob.Read(Buffer, 0, myLength);

                this.Response.Clear();
                //输出mime类型,根据上传的文件取到的mimetype  
                this.Response.ContentType = "xml";
                this.Response.BinaryWrite(Buffer);
                this.Response.End();
            }

            // 关闭连接
            reader.Close();
            connection.Close();
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }
    }

例四:生成xml类

/// <summary>
    /// 根据要求取xml
    /// </summary>
    /// <param name="idName">唯一键名</param>
    /// <param name="IdValue">唯一键值</param>
    /// <param name="tabName">表名</param>
    /// <param name="xmlBlob">xml文件所在字名</param>
    /// <returns>取出的xml文件</returns>
    public static XmlDocument setxmldoc(string idName,string idValue,string tabName,string xmlBlob)
    {
        XmlDocument xmldoc = new XmlDocument();
        string getsqL = "select " + xmlBlob + " from " + tabName + " where " + idName + "='" + idValue + "'";
        OracleConnection connection = GenericClassOra.connect();
        OracleCommand command = new OracleCommand(getsqL, connection);
        try
        {
            connection.Open();
            OracleDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            while (reader.Read())
            {
                OracleLob myLob = reader.GetOracleLob(0);
                //长度是long,转为int32  
                int myLength = Convert.ToInt32(myLob.Length);
                Byte[] Buffer = new byte[myLength];
                myLob.Read(Buffer, 0, myLength);
                //新加
                sb.Append(System.Text.Encoding.Default.GetString(Buffer, 0, myLength));
                //结束
                //this.Response.Clear();
                //输出mime类型,根据上传的文件取到的mimetype  
                //this.Response.ContentType = "xml";
                //this.Response.BinaryWrite(Buffer);
                //this.Response.End();
            }
            xmldoc.LoadXml(sb.ToString());               
            // 关闭连接
            reader.Close();
            connection.Close();
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }           
        return xmldoc;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值