[转贴]在 .NET 中使用大对象

在 .NET 中使用大对象
作者:Jason Price

了解如何使用 .NET 读写大对象 (LOB) 以及如何通过 BFILE 读取数据。

本文相关下载:
· 示例代码
· Oracle 数据库 10g
· ODP.NET(版本 10.1.0.2.0 或更高版本,如果需要的话)
· Microsoft .NET Framework 和 SDK 

 

本文是上一篇介绍在 .NET 中使用数据库对象文章的后续文章。在本文中,您将了解如何在 Visual Basic .NET (VB.NET) 和 Visual C# .NET (C#) 中使用大对象。尤其是,您将了解如何使用 .NET 读写大对象 (LOB)。您还将了解如何通过 BFILE(可以将其看作是文件指针)读取数据。本文中引用的所有脚本和文件都可在这里找到。本文假定您大体上了解 C# 和 VB.NET 编程。

本文适用于开发人员,您应大体上了解 C# 和 VB.NET 编程并具有 LOB 基础知识。如果您需要 LOB 的介绍,可以阅读 Oracle LOB 文档,也可以阅读我编写的 Oracle 数据库 10g SQL(McGraw-Hill/Osborne,2004)一书。


所需软件
如果您要跟随我们逐步完成本文中给出的示例,那么您需要安装以下软件:

Windows NT 4.0、Windows 2000、Windows XP Professional 或 Windows Server 2003
访问已安装好的 Oracle 数据库
Oracle 客户机(版本 10.1.0.2.0 或更高版本)
Oracle Net(版本 10.1.0.2.0 或更高版本)
Oracle Data Providers for .NET(版本 10.1.0.2.0 或更高版本,如果需要的话)
Microsoft .NET Framework(版本 1.0 或更高版本)
Microsoft .NET 框架 SDK(版本 1.0 或更高版本)
注意:如果您使用的是 Oracle 数据库 10g(Oracle8i 版本 3 8.1.7 或更高版本)之前的版本,则需要在数据库之外单独下载和安装 Oracle Data Provider for .NET (ODP.NET)。

ODP.NET 驱动程序针对 Oracle 数据库访问进行了优化,因此可以获得最佳性能,并且它们还支持 Oracle 数据库的丰富特性,如 BFILE、BLOB、CLOB、XMLType 等。如果您正在开发基于 Oracle 数据库的 .NET 应用程序,那么就特性和性能来讲,ODP.NET 无疑是最佳的选择。

注意:ODP.NET 驱动程序针对 Oracle 数据库访问进行了优化,因此可以获得最佳性能,并且它们还支持 Oracle 数据库的丰富特性,如 BFILE、BLOB、CLOB、XMLType 等。如果您正在开发基于 Oracle 数据库的 .NET 应用程序,那么就特性和性能来讲,ODP.NET 无疑是最佳的选择。

数据库模式设置

首先,您需要设置将包含本文所用表的数据库模式。您首先必须创建一个名为 lob_user 的用户,并按如下所示授予该用户所需权限。(您必须先以具有数据库管理员权限的用户身份登录数据库,才能创建用户和授予权限):

CREATE USER lob_user IDENTIFIED BY lob_password;
GRANT CONNECT, RESOURCE, CREATE ANY DIRECTORY TO lob_user;
您会在示例代码文件 lob_db.sql 中找到前两个语句和该部分中出现的设置 store 模式的其他语句。

以下语句创建一个名为 SAMPLE_FILES_DIR 的目录,该目录指向服务器硬盘驱动器上的 C:/sample_files 目录;您必须在硬盘驱动器的 C: 分区中创建 sample_files 目录,并将 textContent.txt 和 binaryContent.doc 文件复制到 C:/sample_files 中。

CREATE OR REPLACE DIRECTORY SAMPLE_FILES_DIR AS 'C:/sample_files';注意:textContent.txt 和 binaryContent.doc 文件包含莎士比亚戏剧 Macbeth 中的引文。您不久将看到把这两个文件的内容复制到数据库中。


下一语句授予公众读取权限,以便所有用户均可读取 SAMPLE_FILES_DIR 的内容:
GRANT READ ON DIRECTORY SAMPLE_FILES_DIR TO PUBLIC;
下一语句以 lob_user 的身份连接:

CONNECT lob_user/lob_password;
您将看到本文使用了三个表:

clob_content:包含一个名为 clob_column 的 CLOB 列。该列用于存储 textContent.txt 文件中包含的字符数据。
blob_content:包含一个名为 blob_column 的 BLOB 列。该列用于存储 binaryContent.doc 文件中存储的二进制数据。
bfile_content:包含一个名为 bfile_column 的 BFILE 列。该列用于存储两个外部文件的指针。
以下语句创建 clob_content、blob_content 和 bfile_content 等表:
如果您创建了这些表所用的模式不是 lob_user 的模式,那么您将需要修改稍后的示例程序中的模式名称。

CREATE TABLE clob_content (
id          INTEGER PRIMARY KEY,
clob_column CLOB NOT NULL
);

CREATE TABLE blob_content (
id          INTEGER PRIMARY KEY,
blob_column BLOB NOT NULL
);

CREATE TABLE bfile_content (
id           INTEGER PRIMARY KEY,
bfile_column BFILE NOT NULL
);

 

下两条语句向 clob_content 和 blob_content 表中添加一个空的 CLOB 和 BLOB:

INSERT INTO clob_content (
id, clob_column
) VALUES (
1, EMPTY_CLOB()
);

INSERT INTO blob_content (
id, blob_column
) VALUES (
1, EMPTY_BLOB()
);

 

DECLARE
my_clob  CLOB;
my_blob  BLOB;
my_bfile BFILE;
BEGIN
-- load the CLOB
my_bfile := BFILENAME('SAMPLE_FILES_DIR', 'textContent.txt');
SELECT clob_column
INTO my_clob
FROM clob_content
WHERE id = 1 FOR UPDATE;
DBMS_LOB.FILEOPEN(my_bfile, dbms_lob.file_readonly);
DBMS_LOB.LOADFROMFILE(my_clob, my_bfile, DBMS_LOB.GETLENGTH(my_bfile), 1, 1);

-- load the BLOB
my_bfile := BFILENAME('SAMPLE_FILES_DIR', 'binaryContent.doc');
SELECT blob_column
INTO my_blob
FROM blob_content
WHERE id = 1 FOR UPDATE;
DBMS_LOB.FILEOPEN(my_bfile, dbms_lob.file_readonly);
DBMS_LOB.LOADFROMFILE(my_blob, my_bfile, DBMS_LOB.GETLENGTH(my_bfile), 1, 1);

DBMS_LOB.FILECLOSEALL();
COMMIT;
END;
/

 

INSERT INTO bfile_content (
id,
bfile_column
) VALUES (
  1,
BFILENAME('SAMPLE_FILES_DIR', 'textContent.txt')
);
使用 C# 和 VB.NET 从 LOB 中读取数据

检索 LOB 有两种方法:

使用 LOB 定位器延迟 LOB 检索:ODP.NET 在数据库服务器上检索 LOB 的指针。在应用程序开始读取 LOB 之前不检索实际的 LOB 数据。对于 CLOB,应使用 Oracle.DataAccess.Types.OracleClob 类的对象存储使用 OracleDataReader 对象的 GetOracleClob() 方法读取的定位器,然后使用 Read() 方法访问 OracleClob 中存储的数据。对于 BLOB,应使用 Oracle.DataAccess.Types.OracleBlob 对象和 GetOracleBlob() 方法。
立即检索所有或大量 LOB 数据:ODP.NET 将在 SELECT 语句执行时检索所有 LOB 的 LOB 数据。对于 CLOB,应使用 OracleDataReader 的 GetString()、GetChars()、GetValue() 或 GetOracleString() 方法读取数据。对于 BLOB,应使用 GetBytes()、GetValue()、GetValues() 或 GetOracleBinary() 方法。
在第二种情况下,第一个数据库往返从 LOB 读取的数据量取决于 OracleDataReader 对象的 InitialLOBFetchSize 属性的设置,它的值从 OracleCommand 对象中继承。InitialLOBFetchSize 的默认值为 0 — 即 LOB 数据检索将推迟到程序显式请求该数据(即第一种情况)时进行。如果将 InitialLOBFetchSize 更改为大于零的值,则在一个往返中将立即检索 LOB 数据,最多为在 InitialLOBFetchSize 中指定的字节或字符数。
此参数影响 SELECT 语句执行中的所有 LOB。例如,如果将 InitialLOBFetchSize 设置为 5K,且在 SELECT 语句执行中将检索 10 个 LOB,则在一个数据库往返中将检索这 10 个 LOB 中每个 LOB 的前 5K。当前,10.1.0.2.0 版的 ODP.NET 中 InitialLOBFetchSize 的最大设置为 32KB。Oracle 将在未来版本中将此最大大小增大为 2GB。

注意:如果更改 InitialLOBFetchSize(默认值 0),则您只能使用上面提到的方法 2 中的访问器从 CLOB 中读取数据 — 不过 Oracle 计划移除该限制。在未来的 ODP.NET 版本中,您将能够使用这两个方法来检索 LOB。

如果您选择的所有 LOB 的数据量不大,且选择了很多 LOB,则通过更改 InitialLOBFetchSize(默认值 0),您可能获得更出色的立即检索 LOB 数据性能。如果使用 InitialLOBFetchSize,则应将其设置为一个略大于所选 LOB 大小的 80% 的值。例如,如果行中 LOB 大小的 80% 小于或等于 1KB,则应将 InitialLOBFetchSize 设置为 1KB。由于结果将取决于网络性能、延迟、数据大小等因素,因此应试验您的设置以发现 InitialLOBFetchSize 的最优设置。

更改 InitialLOBFetchSize 的默认值 0 时,将进行立即 LOB 检索。当保留 InitialLOBFetchSize 的默认值零 0 时,将进行延迟 LOB 检索。下表提供了决定使用延迟 LOB 检索还是立即 LOB 检索时要考虑的原则。

在以下情况下使用延迟 LOB 检索 在以下情况下使用立即 LOB 检索
客户端和数据库服务器之间的网络带宽不足 网络带宽充足
您不需要立即对大部分 LOB 数据进行立即访问,而是可以随着时间的推移来检索它 您需要在选中 LOB 数据时立即读取几乎所有这些数据
您正在执行更新、插入或删除,不打算读取 LOB N/A

使用延迟 LOB 检索从 LOB 中读取数据


接下来,我们将逐步完成四个示例程序(使用 LOB 定位器读取先前存储在 clob_content.clob_column 中的文本和存储在 blob_content.blob_column 中的二进制数据)中的主要步骤。这四个程序如下所示:
ClobExample1.cs,一个从 clob_content.clob_column 中读取数据的 C# 程序
ClobExample1.vb,与 ClobExample1.cs 相同,但用 VB.NET 编写
BlobExample1.cs,一个从 blob_content.blob_column 中读取数据的 C# 程序
BlobExample1.vb,与 BlobExample1.cs 相同,但用 VB.NET 编写。
注意:有关如何编译 C# 和 VB.NET 程序的信息,请阅读我的技术文章“在 .NET 中使用 Oracle 数据库事务”。

第 1 步
ClobExample1.cs 中的第 1 步从 clob_content 表中读取行:

myOracleCommand.CommandText =
"SELECT id, clob_column " +
"FROM clob_content " +
"WHERE id = 1";
OracleDataReader myOracleDataReader =
myOracleCommand.ExecuteReader();
myOracleDataReader.Read();
在 ClobExample1.vb 中,VB.NET 代码为

myOracleCommand.CommandText = _
"SELECT id, clob_column " & _
"FROM clob_content " & _
"WHERE id = 1"
Dim myOracleDataReader As _
OracleDataReader = myOracleCommand.ExecuteReader()
myOracleDataReader.Read()

 

myOracleCommand.CommandText =
"SELECT id, blob_column " +
"FROM blob_content " +
"WHERE id = 1";
OracleDataReader myOracleDataReader =
myOracleCommand.ExecuteReader();
myOracleDataReader.Read();
在 BlobExample1.vb 中,VB.NET 代码为

myOracleCommand.CommandText = _
"SELECT id, blob_column " & _
"FROM blob_content " & _
"WHERE id = 1"
Dim myOracleDataReader As _
OracleDataReader = myOracleCommand.ExecuteReader()
myOracleDataReader.Read()
第 2 步

ClobExample1.cs 中的第 2 步将 LOB 定位器复制给 OracleClob 对象。使用 myOracleDataReader.GetOracleClob() 方法取得定位器:

OracleClob myOracleClob = myOracleDataReader.GetOracleClob(1);
在 ClobExample1.vb 中,VB.NET 代码为

Dim myOracleClob As _
OracleClob = myOracleDataReader.GetOracleClob(1)

BlobExample1.cs 中的第 2 步将 LOB 定位器复制给 OracleBlob 对象。使用 myOracleDataReader.GetOracleBlob() 方法取得定位器:

OracleBlob myOracleBlob = myOracleDataReader.GetOracleBlob(1);
在 BlobExample1.vb 中,VB.NET 代码为

Dim myOracleBlob As _
OracleBlob = myOracleDataReader.GetOracleBlob(1)

第 3 步

ClobExample1.cs 中的第 3 步使用 OracleClob 对象的 Read() 方法取得 CLOB 数据。Read() 方法有两个版本:

int Read(byte [] byteArray, int offset, int count)
int Read(char [] charArray, int offset, int count)

其中:
返回的 int 是读取的字节或字符数
byteArray 和 charArray 是将数据读入的数组
offset 是将数据写到的数组中的位置
count 是要读取的字节或字符数。
在 ClobExample1.cs 的以下代码中您将看到,从 CLOB 读取字符并将其写入名为 charArray 的字符数组中。此示例代码将在每个数据库往返中一次读取 CLOB 50 个字符,直到读取了整个 CLOB。
char [] charArray = new char[50];
int numCharsRead;
while ((numCharsRead = myOracleClob.Read(charArray, 0, 50)) > 0)
{
Console.WriteLine("numCharsRead = " + numCharsRead);
string clobData = new string(charArray, 0, numCharsRead);
Console.WriteLine("clobData = " + clobData);
}
在 ClobExample1.vb (VB.NET) 中:

Dim charArray(50) As char
Dim numCharsRead As Integer
numCharsRead = myOracleClob.Read(charArray, 0, 50)
Do While (numCharsRead > 0)
Console.WriteLine("numCharsRead = " & numCharsRead)
Dim clobData As New string(charArray, 0, numCharsRead)
Console.WriteLine("clobData = " & clobData)
numCharsRead = myOracleClob.Read(charArray, 0, 50)
Loop
BlobExample1.cs 中的第 3 步使用 OracleBlob 对象的 Read() 方法。Read() 方法只有一个版本:

int Read(byte [] byteArray, int offset, int count)
在 BlobExample1.cs 的以下 C# 代码中您将看到,从 BLOB 读取字符并将其写入名为 byteArray 的字符数组中。此示例代码将在每个数据库往返中一次读取 BLOB 50 个字符,直到读取了整个 BLOB。

byte [] byteArray = new byte[50];
Console.WriteLine("byteArray.Length = " + byteArray.Length);
int numBytesRead;
while ((numBytesRead = myOracleBlob.Read(byteArray, 0, 50)) > 0)
{
Console.WriteLine("numBytesRead = " + numBytesRead);
}
在 BlobExample1.vb 中,VB.NET 代码为

Dim byteArray(50) As byte
Dim numBytesRead As Integer
numBytesRead = _
myOracleBlob.Read(byteArray, 0, 50)
Do While (numBytesRead > 0)
Console.WriteLine("numBytesRead = " & numBytesRead)
numBytesRead = _
myOracleBlob.Read(byteArray, 0, 50)
Loop
使用立即 LOB 检索从 LOB 中读取数据


现在,我将逐步完成四个示例程序(使用立即 LOB 检索读取先前存储在 clob_content.clob_column 中的文本和存储在 blob_content.blob_column 中的二进制数据)中的主要步骤。这四个程序如下所示:
ClobExample2.cs,一个从 clob_content.clob_column 中读取数据的 C# 程序
ClobExample2.vb,与上一个程序相同,但用 VB.NET 编写
BlobExample2.cs,一个从 blob_content.blob_column 中读取数据的 C# 程序
BlobExample2.vb,与上一个程序相同,但用 VB.NET 编写。
我还将在第 1 步中向您演示如何更改 InitialLOBFetchSize。正如我在前面提到的,将 InitialLOBFetchSize 更改为一个大于零的值将导致立即检索数目最大为在 InitialLOBFetchSize 中指定的字节或字符数的 LOB 数据。
第 1 步

第 1 步将 InitialLOBFetchSize 设置为 1,000 个字节。在 ClobExample2.cs 和 BlobExample2.cs 中,C# 代码为

myOracleCommand.InitialLOBFetchSize = 1000;
注意,是在 OracleCommand 对象上设置 InitialLOBFetchSize。在 ClobExample2.vb 和 BlobExample2.vb 中,VB.NET 代码为

myOracleCommand.InitialLOBFetchSize = 1000
第 2 步

第 2 步与前面的延迟 LOB 检索示例显示的第 1 步相同。

第 3 步

ClobExample2.cs 中的第 3 步使用 GetString() 方法从 CLOB 中取得数据并显示该数据:

String clobData = myOracleDataReader.GetString(1);
Console.WriteLine("clobData = " + clobData);
在 ClobExample2.vb 中,VB.NET 代码为

Dim clobData As string = myOracleDataReader.GetString(1)
Console.WriteLine("clobData = " & clobData)
BlobExample2.cs 中的第 3 步使用 GetBytes() 方法从 BLOB 中取得数据并显示读取的字节数:

byte [] byteArray = new byte[1000];
long numBytesRead = myOracleDataReader.GetBytes(1, (long) 0, byteArray, 0, 1000);
Console.WriteLine("numBytesRead = " + numBytesRead);
在 BlobExample2.vb 中,VB.NET 代码为

Dim byteArray(1000) As byte
Dim numBytesRead As long = _
myOracleDataReader.GetBytes(1, 0, byteArray, 0, 1000)
Console.WriteLine("numBytesRead = " & numBytesRead)
使用 C# 和 VB.NET 写入 LOB

使用 OracleDataReader 对象时有两种方法可以写入 LOB:

对于 CLOB,调用 OracleDataReader 的 GetOracleClobForUpdate() 方法。对于 BLOB,调用 GetOracleBlobForUpdate() 方法。
将 FOR UPDATE 子句添加到 SELECT 语句,然后调用 GetOracleClob() 或 GetOracleBlob() 方法取得 CLOB 或 BLOB。
至于选择哪种方法完全取决于个人偏好。方法之间不存在性能优劣。对于任何一种方法,当您在 OracleClob 或 OracleBlob 中使用 CLOB 或 BLOB 定位器后,应使用 OracleClob 或 OracleBlob 的 Write() 方法写入 LOB。使用定位器访问 LOB 的优点是,在写入 LOB 之前,最初不必将数据下载到中间层。
使用方法 1 写入 CLOB

我将逐步完成两个示例程序(使用方法 1 写入 clob_content.clob_column 中的 CLOB)中的主要步骤。这两个程序如下所示:

ClobExample3.cs,一个写入 clob_content.clob_column 的 C# 程序
ClobExample3.vb,与上一个程序一样,但用 VB 编写。
由于写入 BLOB 的步骤相似,因此我只演示写入 CLOB 的代码。
第 1 步

必须在 OracleTransaction 对象的上下文中执行所有 LOB 更新。在 ClobExample3.cs 中,C# 代码为

OracleTransaction myOracleTransaction = myOracleConnection.BeginTransaction();
在 ClobExample3.vb 中,VB.NET 代码为

Dim myOracleTransaction As OracleTransaction = _
myOracleConnection.BeginTransaction()
第 2 步

第 2 步是读取行,它与前面的“使用延迟 LOB 检索从 LOB 中读取数据”部分中的第 1 步相同。

第 3 步

第 3 步是使用 OracleDataReader 的 GetOracleClobForUpdate() 方法取得 LOB 定位器。在 ClobExample3.cs 中,C# 代码为

OracleClob myOracleClob = myOracleDataReader.GetOracleClobForUpdate(1);
在 ClobExample3.vb 中,VB.NET 代码为

Dim myOracleClob As _
OracleClob = myOracleDataReader.GetOracleClobForUpdate(1)
第 4 步

第 4 步是使用 OracleClob 对象的 Write() 方法写入 CLOB。Write() 方法有两个版本:

Write(byte [] byteArray, int offset, int count)
Write(char [] charArray, int offset, int count)
其中:

byteArray 和 charArray 是包含要写入 CLOB 的数据的数组
offset 是将数据写到 CLOB 中的位置
count 是要写入的字节或字符数。
在 ClobExample3.cs 的以下 C# 代码中,注意我首先使用 Erase() 方法删除了 myOracleClob 的当前内容;写入 myOracleClob 之前不必执行该操作,执行该操作只是为了删除现有文本。
myOracleClob.Erase();
string text = "It is the east, and Juliet is the Sun";
char [] charArray = text.ToCharArray();
myOracleClob.Write(charArray, 0, charArray.Length);
Console.WriteLine("myOracleClob.Value = " + myOracleClob.Value);
在 ClobExample3.vb 中,VB.NET 代码为

myOracleClob.Erase()
Dim text As string = "It is the east, and Juliet is the Sun"
Dim charArray() As char = text.ToCharArray()
myOracleClob.Write(charArray, 0, charArray.Length)
Console.WriteLine("myOracleClob.Value = " & myOracleClob.Value)
第 5 步

第 5 步是提交事务,以便将新文本永久存储在数据库中。在 ClobExample3.cs 中,C# 代码为

myOracleTransaction.Commit();
在 ClobExample3.vb 中,VB.NET 代码为

myOracleTransaction.Commit()
使用方法 2 写入 CLOB

现在,我们将逐步完成两个示例程序(使用方法 2 写入 clob_content.clob_column 中的 CLOB)中的主要步骤。这两个程序如下所示:

ClobExample4.cs,一个写入 clob_content.clob 的 C# 程序
ClobExample4.vb,与上一个程序相同,但用 VB.NET 编写。
只有第 2 步和第 3 步与方法 1 中所示步骤不同。

第 2 步

第 2 步从 clob_content 中读取行。对于方法 2,将 FOR UPDATE 子句添加到 SELECT 语句。在 ClobExample4.cs 中,C# 代码为
myOracleCommand.CommandText =
"SELECT id, clob_column " +
"FROM clob_content " +
"WHERE id = 1 FOR UPDATE";
OracleDataReader myOracleDataReader =
myOracleCommand.ExecuteReader();
myOracleDataReader.Read();
在 ClobExample4.vb 中,VB.NET 代码为

myOracleCommand.CommandText = _
"SELECT id, clob_column " & _
"FROM clob_content " & _
"WHERE id = 1 FOR UPDATE"
Dim myOracleDataReader As _
OracleDataReader = myOracleCommand.ExecuteReader()
myOracleDataReader.Read()
第 3 步


第 3 步取得 CLOB 定位器。在 ClobExample4.cs 中,C# 代码为
OracleClob myOracleClob = myOracleDataReader.GetOracleClob(1);
在 ClobExample4.vb 中,VB.NET 代码为

Dim myOracleClob As OracleClob = _
myOracleDataReader.GetOracleClob(1)
以下是该步骤与前一方法中所示步骤的差别:此处我调用 GetOracleClob(),而前面我调用了 GetOracleClobForUpdate()。由于第 2 步中使用了 FOR UPDATE 子句,因此我不必使用 GetOracleClobForUpdate() — 我只需调用 GetOracleClob() 并开始写入 CLOB。一旦拥有 CLOB 定位器,写入 CLOB 的步骤则与上面的方法 1 完全相同。

使用 C# 和 VB.NET 从 BFILE 中读取数据

BFILE 存储文件系统中文件的指针,您可以通过该指针访问该文件。我将逐步完成两个示例程序(读取由 bfile_content.bfile_column 中的 BFILE 指向的 textContent.txt 文件中的文本)中的主要步骤。这两个程序如下所示:

BfileExample1.cs,一个 C# 程序
BfileExample1.vb,上一程序的 VB.NET 版本。
第 1 步

第 1 步从 bfile_content 表中读取行。在 BfileExample1.cs,C# 代码为
myOracleCommand.CommandText =
"SELECT id, bfile_column " +
"FROM bfile_content " +
"WHERE id = 1";
OracleDataReader myOracleDataReader =
myOracleCommand.ExecuteReader();
myOracleDataReader.Read();
在 BfileExample1.vb 中,VB.NET 代码为

myOracleCommand.CommandText = _
"SELECT id, bfile_column " & _
"FROM bfile_content " & _
"WHERE id = 1"
Dim myOracleDataReader As OracleDataReader = _
myOracleCommand.ExecuteReader()
myOracleDataReader.Read()
第 2 步


第 2 步通过调用 OracleDataReader 对象的 GetOracleBFile() 方法取得 BFILE。在 BfileExample1.cs 的以下 C# 代码中您将看到,我还将显示目录名、文件名以及文件是否存在:
OracleBFile myOracleBFile = myOracleDataReader.GetOracleBFile(1);
Console.WriteLine("myOracleBFile.DirectoryName = " +
myOracleBFile.DirectoryName);
Console.WriteLine("myOracleBFile.FileName = " +
myOracleBFile.FileName);
Console.WriteLine("myOracleBFile.FileExists = " +
myOracleBFile.FileExists);
在 BfileExample1.vb 中,VB.NET 代码为

Dim myOracleBFile As OracleBFile = _
myOracleDataReader.GetOracleBFile(1)
Console.WriteLine("myOracleBFile.DirectoryName = " & _
myOracleBFile.DirectoryName)
Console.WriteLine("myOracleBFile.FileName = " & _
myOracleBFile.FileName)
Console.WriteLine("myOracleBFile.FileExists = " & _
myOracleBFile.FileExists)
第 3 步

BfileExample1.cs 中的第 3 步打开 BFILE:

myOracleBFile.OpenFile();
在 BfileExample1.vb 中,VB.NET 与上一程序相同。

第 4 步


BfileExample1.cs 中的第 4 步使用 Read() 方法从 BFILE 中读取数据。在以下代码中您将看到,BFILE 中的数据被读入名为 byteArrray 的字节数组中;同时,还使用 System.Text.Encoding.ASCII.GetString() 方法将该数组中的数据转换为字符串,以便在屏幕上显示数据:
byte [] byteArray = new byte[1000];
int offset = 0;
int numBytesRead;
while ((numBytesRead = myOracleBFile.Read(byteArray, offset, 1000-offset)) > 0)
{
Console.WriteLine("numBytesRead = " + numBytesRead);
String text =
System.Text.Encoding.ASCII.GetString(byteArray, 0, numBytesRead);
Console.WriteLine("text = " + text);
offset += numBytesRead;
}

在 BfileExample1.vb 中,VB.NET 代码为

Dim byteArray(1000) As byte
Dim offset As Integer = 0
Dim numBytesRead As Integer
numBytesRead = myOracleBFile.Read(byteArray, offset, 1000-offset)
Do While (numBytesRead > 0)
Console.WriteLine("numBytesRead = " & numBytesRead)
Dim text As string = _
System.Text.Encoding.ASCII.GetString(byteArray, 0, numBytesRead)
Console.WriteLine("text = " & text)
offset += numBytesRead
numBytesRead = myOracleBFile.Read(byteArray, offset, 1000-offset)
Loop                             
第 5 步

BfileExample1.cs 中的第 5 步使用 Close() 方法关闭 BFILE:

myOracleBFile.Close();                  
在 BfileExample1.vb 中,VB.NET 与上一程序相同。


结论
本文介绍了如何从 C# 和 VB.NET 访问大对象。您还了解了如何通过 BFILE 读取数据

BlobExample1.cs 中的第 1 步从 blob_content 表中读取行: 下一条语句使 bfile_content 表中的 BFILE 指向位于 SAMPLE_FILES_DIR 目录中的 textContent.txt 文件: 下列 PL/SQL 语句将文件 textContent.txt 中的文本加载到 clob_content 表中,将文件 binaryContent.doc 中的二进制数据加载到 blob_content 表中:

你可能感兴趣的:(c#)