直接上代码。
/// <summary>
/// 从数据库读取Lob到文件
/// </summary>
private void ReadLobToFile()
{
const int employeeIdColumn = 0;
const int employeePhotoColumn = 1;
const int bufferSize = 100;
byte[] buffer = new byte[bufferSize];
int byteCountRead;
long currentIndex = 0;
ConnectionStringSettings nwSetting = ConfigurationManager.ConnectionStrings["NorthWindDb"];
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = nwSetting.ConnectionString;
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "Select EmployeeID,Photo From Employees";
/*SequentialAccess 不是加载整行,而是使 DataReader 将数据作为流来加载。
然后可以使用 GetBytes 或 GetChars 方法来指定开始读取操作的字节位置以及正在返回的数据的有限的缓冲区大小。
*/
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (rdr.Read())
{
int employeeId = rdr.GetInt32(employeeIdColumn);
string fileName = @"D:\Employee" + employeeId.ToString().PadLeft(2, '0') + ".bin";
using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
{
currentIndex = 0;
//从指定的列偏移量将字节流读入缓冲区,并将其作为从给定的缓冲区偏移量开始的数组。
/*
参数
i
类型:Int32 从零开始的列序号。
dataIndex
类型:Int64 字段中的索引,从其开始读取操作。
buffer
类型:array<Byte>[]()[] 要将字节流读入的缓冲区。
bufferIndex
类型:Int32 buffer 中写入操作开始位置的索引。
length
类型:Int32 要复制到缓冲区中的最大长度。
*/
byteCountRead = (int)rdr.GetBytes(employeePhotoColumn, currentIndex, buffer, 0, bufferSize);
while (byteCountRead != 0)
{
fs.Write(buffer, 0, byteCountRead);
currentIndex += byteCountRead;
byteCountRead = (int)rdr.GetBytes(employeePhotoColumn, currentIndex, buffer, 0, bufferSize);
}
}
}
}
}
}
/// <summary>
/// 得到头信息及图片
/// 该代码检查该照片是否包含OLE头信息。如果包含将从OLE头信息后面开始执行写操作。
/// </summary>
private void GetHeadInfo()
{
//OLE头信息大小为78
const int oleOffset = 78;
//扩展名开始
const int oleTypeStart = 20;
//扩展名占用长度
const int oleTypeLength = 12;
const int employeeIdColumn = 0;
const int employeePhotoColumn = 1;
const int bufferSize = 100;//must be bigger than oleOffset
byte[] buffer = new byte[bufferSize];
int bufferStart = 0;
int byteCountRead;
long currentIndex = 0;
ConnectionStringSettings nwSetting = ConfigurationManager.ConnectionStrings["NorthWindDb"];
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = nwSetting.ConnectionString;
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "Select EmployeeID,Photo From Employees";
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (rdr.Read())
{
int employeeId = rdr.GetInt32(employeeIdColumn);
//文件路径
string fileName = @"D:\Employee\Employee" + employeeId.ToString().PadLeft(2, '0') + ".bin";
using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
{
currentIndex = 0;
while (currentIndex < oleOffset)
{
//第一批次读取
byteCountRead = (int)rdr.GetBytes(employeePhotoColumn, currentIndex, buffer,
(int)currentIndex, bufferSize - (int)currentIndex);
if (byteCountRead == 0)
{
break;
}
currentIndex += byteCountRead;
}
byteCountRead = (int)currentIndex;
if (byteCountRead >= oleOffset)
{
//得到文件类型
string type = Encoding.ASCII.GetString(buffer, oleTypeStart, oleTypeLength);
if (type == "Bitmap Image")
{
//第一批次,从头信息后开使读取
bufferStart = oleOffset;
//第一批次的读取大小
byteCountRead = byteCountRead - oleOffset;
}
}
//写入文件
while (byteCountRead != 0)
{
fs.Write(buffer, bufferStart, byteCountRead);
bufferStart = 0;
byteCountRead = (int)rdr.GetBytes(employeePhotoColumn, currentIndex, buffer, 0, bufferSize);
currentIndex += byteCountRead;
}
}
}
}
}
}
/// <summary>
/// 将图片写入到数据库
/// </summary>
private void WriteBlobToDb()
{
const int bufferSize = 100;
byte[] buffer = new byte[bufferSize];
long currentIndex = 0;
byte[] photoPtr;
ConnectionStringSettings nwSetting = ConfigurationManager.ConnectionStrings["NorthWindDb"];
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = nwSetting.ConnectionString;
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "select Textptr(Photo) from employees where employeeID='1'";
photoPtr = (byte[])cmd.ExecuteScalar();
}
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "UpdateText employees.Photo @Pointer @Offset null @Data";
SqlParameter ptrParm = cmd.Parameters.Add("Pointer", SqlDbType.Binary, 16);
ptrParm.Value = photoPtr;
SqlParameter PhotoParm = cmd.Parameters.Add("Data", SqlDbType.Image);
SqlParameter offsetParm = cmd.Parameters.Add("Offset", SqlDbType.Int);
offsetParm.Value = 0;
using (FileStream fs = new FileStream("Girl.png", FileMode.Open, FileAccess.Read))
{
int count = fs.Read(buffer, 0, bufferSize);
while (count != 0)
{
PhotoParm.Value = buffer;
PhotoParm.Size = count;
cmd.ExecuteNonQuery();
currentIndex += count;
offsetParm.Value = currentIndex;
count = fs.Read(buffer, 0, bufferSize);
}
}
}
}
MessageBox.Show("Done");
}
/// <summary>
/// 显示有头信息的图片
/// </summary>
private void ShowImgHaveHead()
{
const int bufferSize = 100;
byte[] buffer = new byte[bufferSize];
long currentIndex = 0;
byte[] OleArray;
byte[] photoPtr;
ConnectionStringSettings nwSetting = ConfigurationManager.ConnectionStrings["NorthWindDb"];
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = nwSetting.ConnectionString;
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "select Photo from employees where employeeID='2'";
OleArray = (byte[])cmd.ExecuteScalar();
photoPtr = new byte[OleArray.Length - 78];
//去除头信息(如此BLob中前78个字节为头信息)
Array.Copy(OleArray, 78, photoPtr, 0, (OleArray.Length - 78));
using (MemoryStream ms = new MemoryStream(photoPtr))
{
Bitmap bmp = new Bitmap(ms);
ptbImg.Image = bmp;
}
}
}
MessageBox.Show("Done");
}
/// <summary>
/// 显示没有头文信息的图片
/// </summary>
private void ShowImgNoHead()
{
const int bufferSize = 100;
byte[] buffer = new byte[bufferSize];
byte[] photoPtr;
ConnectionStringSettings nwSetting = ConfigurationManager.ConnectionStrings["NorthWindDb"];
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = nwSetting.ConnectionString;
cn.Open();
using (SqlCommand cmd = cn.CreateCommand())
{
cmd.CommandText = "select Photo from employees where employeeID='2'";
photoPtr = (byte[])cmd.ExecuteScalar();
using (MemoryStream ms = new MemoryStream(photoPtr))
{
Bitmap bmp = new Bitmap(ms);
ptbImg.Image = bmp;
}
}
}
MessageBox.Show("Done");
}