上传和下载 BLOB 到 Microsoft Access






4.71/5 (6投票s)
2006 年 12 月 21 日
3分钟阅读

183266

8130
演示如何上传和下载 BLOB 数据到 Microsoft Access。
引言
AccessBlob 演示如何上传和下载二进制大对象 (BLOB) 到 Microsoft Access 数据库。 描述 BLOB 最简单的方法是将其视为存储在关系数据库字段中的文件。 BLOB 可以是图像文件、电子表格、文字处理文件等。 Web 上有很多用于上传和下载 BLOB 到 SQL Server 的代码片段,但我找不到任何用于 Microsoft Access 的代码片段。
本文附带的示例应用程序仅用于演示如何上传和下载 BLOB 数据到 Microsoft Access 数据库。 示例应用程序附带一个 Microsoft Access 2000 数据库。 使用该应用程序时,“数据文件”的文本框包含磁盘上文件的完整路径名。 此字段用于要上传的文件和要下载的文件。 下载时,还必须从 listview 中选择要下载的文件。
背景
Microsoft Access 将 BLOB 数据存储在具有 OLE 对象数据类型的字段中(如果您是从设计视图创建表)。 如果您是从 SQL 语句创建表,则数据类型为 IMAGE
(类似于 SQL Server)。 对于此示例应用程序,使用以下 Access 表。
CREATE TABLE File (
FileName VARCHAR(255),
Size INT,
Type VARCHAR(255),
DateUploaded DATETIME,
File IMAGE,
CONSTRAINT File_PK PRIMARY KEY(FileName)
)
上传文件
通过将文件的内存驻留版本分配给 OleDbCommand
对象的参数来上传文件。 使用 BinaryReader
对象将文件加载到内存中,因为我们不希望读取器处理任何数据。 BinaryReader
的构造函数不能接受文件名,因此我们必须首先创建一个 FileStream
并将其传递给 BinaryReader
的构造函数。
我们正在使用的变量是
// the connection to the database
System.Data.OleDb.OleDbConnection conn = null;
// the command
System.Data.OleDb.OleDbCommand cmd = null;
// the data reader used to determine if the
// an insert or update command should be used
System.Data.OleDb.OleDbDataReader dr = null;
// the parameter used to store the BLOB
System.Data.OleDb.OleDbParameter param = null;
// the file stream for the source file
System.IO.FileStream fileStream;
// the reader used to read the source file
System.IO.BinaryReader reader = null;
// the entire file
byte[] data = null;
我们需要获取文件名、类型和文件上传日期。 以下代码为我们执行此操作。
// DataFile.Text is the source file name with full path. we
// need to determine the file name and the type.
string[] arr = DataFile.Text.Split(new char[]{'\\'});
string fileName = arr[arr.Length - 1];
arr = DataFile.Text.Split(new char[]{'.'});
string type = (arr.Length > 1) ? arr[arr.Length - 1] : "";
// get the time stamp when the file was uploaded
string dateUploaded = System.DateTime.Now.ToShortDateString() +
" " + System.DateTime.Now.ToShortTimeString();
int numRecords = 0;
该过程的其余部分是
- 将文件加载到内存中,
- 打开与数据库的连接,
- 确定记录是否已存在;如果记录不存在,我们将在没有 BLOB 数据的情况下添加记录,最后
- 使用 BLOB 数据更新记录。 请注意,BLOB 数据是通过参数传递的。
您可能会发现我们添加记录然后更新 BLOB 数据很奇怪。 这是我将 BLOB 数据放入数据库的唯一方法。 我无法使用 INSERT
语句将 BLOB 数据放入数据库。 代码是
// load the file that we want to upload into memory
fileStream = new System.IO.FileStream(DataFile.Text,
System.IO.FileMode.Open, System.IO.FileAccess.Read);
reader = new System.IO.BinaryReader(fileStream);
data = reader.ReadBytes((int)fileStream.Length);
// open the connection to the database
conn = new System.Data.OleDb.OleDbConnection("Provider=" +
"Microsoft.Jet.OLEDB.4.0;Data Source=" + AccessFile.Text);
conn.Open();
// determine if the file already exists.
// If the file does not already
// exist, add the file to the table.
cmd = new System.Data.OleDb.OleDbCommand("SELECT " +
"COUNT(*) FROM [File] WHERE [FileName]='" + fileName + "'",conn);
dr = cmd.ExecuteReader();
dr.Read();
numRecords = dr.GetInt32(0);
dr.Close();
if(numRecords == 0) {
cmd = new System.Data.OleDb.OleDbCommand("INSERT INTO" +
" [File] ([FileName],[Size],[Type]," +
"[DateUploaded]) VALUES('" + fileName + "'," +
data.Length + ",'" + type + "', #"+
dateUploaded + "#)",conn);
cmd.ExecuteNonQuery();
}
// update the BLOB data based for the record.
cmd = new System.Data.OleDb.OleDbCommand("UPDATE [File] " +
"SET [File]=@file, [Size]=" + data.Length +
", [DateUploaded]=#" + dateUploaded +
"# WHERE [FileName]='" + fileName + "'",conn);
param = cmd.Parameters.Add("@file",
System.Data.OleDb.OleDbType.Binary);
param.Value = data;
cmd.ExecuteNonQuery();
下载文件
下载文件时,从数据库中读取文件到缓冲区,然后将缓冲区写入磁盘。 因为我们正在处理原始二进制数据,所以我们使用 BinaryWriter
写入数据。 BinaryWriter
的构造函数不能接受文件名,因此我们必须首先创建一个 FileStream
并将其传递给 BinaryWriter
的构造函数。
我们用于下载文件的变量是
// the connection to the database
System.Data.OleDb.OleDbConnection conn = null;
// the command
System.Data.OleDb.OleDbCommand cmd = null;
// reads the data
System.Data.OleDb.OleDbDataReader reader = null;
// the file stream for the destination file
System.IO.FileStream fileStream = null;
// the writer used to create the destination file
System.IO.BinaryWriter writer = null;
// the size of the buffer that is read from the database
// an written to the file
int bufferSize = 1000;
// the buffer for the data being transfered from
// the database to the file
byte[] buffer = new byte[bufferSize];
// the start index of the data in the database
long startIndex = 0;
// the number of bytes read from the database
long numberOfBytes = 0;
下载代码的核心是
// create the connection to the database: AccessFile.Text is the full
// path to the Access file.
conn = new System.Data.OleDb.OleDbConnection("Provider" +
"=Microsoft.Jet.OLEDB.4.0;Data Source=" + AccessFile.Text);
// create the SQL command: FileListView.SelectedItems[0].Text is the name
// of the file taken from the List View.
cmd = new System.Data.OleDb.OleDbCommand("SELECT [File] " +
"FROM [File] WHERE [FileName] = '" +
FileListView.SelectedItems[0].Text + "'", conn);
// open up the connection to the database
conn.Open();
// create the DataReader that will get the blob one buffer at a time
reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
// we advance to the first record returned. for this application we
// know that there is atleast one record because we got the file name
// from the List View
reader.Read();
// create the file stream that will save the file to DataFile.Text
fileStream = new System.IO.FileStream(DataFile.Text,
System.IO.FileMode.OpenOrCreate,
System.IO.FileAccess.Write);
// create the writer from the file stream
writer = new System.IO.BinaryWriter(fileStream);
// read in file from the database one
// buffer at a time. when the number
// of bytes read is zero then we know that we are done.
do {
numberOfBytes = reader.GetBytes(0,
startIndex, buffer, 0, bufferSize);
if(numberOfBytes == 0) {
break;
}
writer.Write(buffer, 0, (int) numberOfBytes);
startIndex += numberOfBytes;
} while (true);
writer.Flush();
结论
AccessBlob 演示如何上传和下载 BLOB 数据到 Microsoft Access 数据库以及从中下载。 您还可以使用 OleDbDataAdapter
和 DataSet
上传和下载 BLOB 数据。 如果您熟悉使用 OleDbDataAdapter
,那么将此代码转换为使用 OleDbDataAdapter
和 DataSet
应该没有问题。 我个人觉得使用 OleDbDataAdapter
很麻烦,并且更喜欢通过仅使用 OleDbCommand
对象来保持我的代码简单。