65.9K
CodeProject 正在变化。 阅读更多。
Home

上传和下载 BLOB 到 Microsoft Access

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (6投票s)

2006 年 12 月 21 日

3分钟阅读

viewsIcon

183266

downloadIcon

8130

演示如何上传和下载 BLOB 数据到 Microsoft Access。

AccessBlob

引言

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;

该过程的其余部分是

  1. 将文件加载到内存中,
  2. 打开与数据库的连接,
  3. 确定记录是否已存在;如果记录不存在,我们将在没有 BLOB 数据的情况下添加记录,最后
  4. 使用 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 数据库以及从中下载。 您还可以使用 OleDbDataAdapterDataSet 上传和下载 BLOB 数据。 如果您熟悉使用 OleDbDataAdapter,那么将此代码转换为使用 OleDbDataAdapterDataSet 应该没有问题。 我个人觉得使用 OleDbDataAdapter 很麻烦,并且更喜欢通过仅使用 OleDbCommand 对象来保持我的代码简单。

© . All rights reserved.