使用 ADO 向数据库中存储一张图片
2010-02-05 15:57
411 查看
【备注】本文中所阐述代码应用于我为BS架构业务系统开发的某个 ActiveX 控件中。
我们将向一个典型SQL数据库中的某表的 Image 类型的字段(假设字段名称为“PHOTO”)存储一副图片,实际上 Image 字段是一种二进制流,它是由应用程序负责解释的。因此在这里我们是将其当作 jpg 图像文件。换句话说,把 jpg 文件的原始字节流存储到 Image 字段中去。由于通过内存中转,这种文件的尺寸不宜过大。
我们假设在一个CImage对象中已经加载的就是要保存的图片,同时也打开了相应表的一个用于插入记录的记录集指针 (_RecordsetPtr )。
则相关代码如下:
代码_ReadImage
//id:主键
void ReadImg(int id)
{
_RecordsetPtr pRs = NULL;
_ConnectionPtr pConnection = NULL;
_variant_t varChunk;
HRESULT hr;
//连接字符串
_bstr_t strCnn("Provider=SQLOLEDB;Server=...;Database=...;User ID=...;Password=...;");
try
{
//Open a connection
pConnection.CreateInstance(__uuidof(Connection));
hr = pConnection->Open(strCnn,"","",NULL);
pRs.CreateInstance(__uuidof(Recordset));
//表名略
char cmdText[128];
sprintf(cmdText, "select PHOTO from ... where ID = %d", id);
pRs->Open(cmdText,_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdText);
//read data
long lPhotoSize = pRs->Fields->GetItem("PHOTO")->ActualSize;
long llsRead = 0;
_variant_t varChunk;
BYTE buf[ChunkSize];
printf("lDatalength = %ld\n", lPhotoSize);
//保存到C盘
char filename[128];
sprintf(filename, "C:\\ID_%d.jpg", id);
FILE* stream = fopen(filename, "wb");
while(lPhotoSize > 0)
{
llsRead = lPhotoSize >= ChunkSize? ChunkSize:lPhotoSize;
varChunk = pRs->Fields->GetItem("PHOTO")->GetChunk(llsRead);
for(long index = 0; index < llsRead; index++)
{
SafeArrayGetElement(varChunk.parray, &index, buf+index);
}
fwrite(buf, 1, llsRead, stream);
lPhotoSize -= llsRead;
}
fclose(stream);
printf("Save File Complete: %s\n", filename);
pRs->Close();
pConnection->Close();
}
catch(_com_error &e)
{
// Notify the user of errors if any.
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
CString sError;
sError.Format(_T("Source : %s \n Description : %s\n"),(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
//AfxMessageBox(sError);
//printf("%s\n", sError);
}
}
我们将向一个典型SQL数据库中的某表的 Image 类型的字段(假设字段名称为“PHOTO”)存储一副图片,实际上 Image 字段是一种二进制流,它是由应用程序负责解释的。因此在这里我们是将其当作 jpg 图像文件。换句话说,把 jpg 文件的原始字节流存储到 Image 字段中去。由于通过内存中转,这种文件的尺寸不宜过大。
我们假设在一个CImage对象中已经加载的就是要保存的图片,同时也打开了相应表的一个用于插入记录的记录集指针 (_RecordsetPtr )。
则相关代码如下:
代码_ReadImage
//id:主键
void ReadImg(int id)
{
_RecordsetPtr pRs = NULL;
_ConnectionPtr pConnection = NULL;
_variant_t varChunk;
HRESULT hr;
//连接字符串
_bstr_t strCnn("Provider=SQLOLEDB;Server=...;Database=...;User ID=...;Password=...;");
try
{
//Open a connection
pConnection.CreateInstance(__uuidof(Connection));
hr = pConnection->Open(strCnn,"","",NULL);
pRs.CreateInstance(__uuidof(Recordset));
//表名略
char cmdText[128];
sprintf(cmdText, "select PHOTO from ... where ID = %d", id);
pRs->Open(cmdText,_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdText);
//read data
long lPhotoSize = pRs->Fields->GetItem("PHOTO")->ActualSize;
long llsRead = 0;
_variant_t varChunk;
BYTE buf[ChunkSize];
printf("lDatalength = %ld\n", lPhotoSize);
//保存到C盘
char filename[128];
sprintf(filename, "C:\\ID_%d.jpg", id);
FILE* stream = fopen(filename, "wb");
while(lPhotoSize > 0)
{
llsRead = lPhotoSize >= ChunkSize? ChunkSize:lPhotoSize;
varChunk = pRs->Fields->GetItem("PHOTO")->GetChunk(llsRead);
for(long index = 0; index < llsRead; index++)
{
SafeArrayGetElement(varChunk.parray, &index, buf+index);
}
fwrite(buf, 1, llsRead, stream);
lPhotoSize -= llsRead;
}
fclose(stream);
printf("Save File Complete: %s\n", filename);
pRs->Close();
pConnection->Close();
}
catch(_com_error &e)
{
// Notify the user of errors if any.
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
CString sError;
sError.Format(_T("Source : %s \n Description : %s\n"),(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
//AfxMessageBox(sError);
//printf("%s\n", sError);
}
}
相关文章推荐
- 在oracle 数据库中使用 Blob 字段存储 一张图片并读取
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- 如何在报表中直接使用数据库中存储的图片
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- J2EE使用hibernate存储和显示BLOB图片(从页面到数据库)
- 如何在报表中直接使用数据库中存储的图片
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- VC++下使用ADO编写数据库程序
- VC++下使用ADO操作数据库的智能指针_ConnectionPtr、_RecordsetPtr、_CommandPtr的方法
- 使用存储过程(PL/SQL)向数据库中存储BLOB对象
- 如何通过使用 ADO.NET 2005 和 Visual C# 2005 或使用 ADO.NET 和 Visual C# .NET 连接到数据库并运行命令
- 使用dbutils工具向数据库中存储大数据
- [2004-8-4]VB.Net学习笔记,使用ADO.Net对象访问数据库,将结果写入ListView
- html5本地存储之localstorage 、本地数据库、sessionStorage简单使用示例
- Android创建和使用数据库详… 分类: Android数据存储 2014-05-30 10:58 82人阅读 评论(0) 收藏
- android数据库存储方法(一)---------------SharedPreferences(实例)记录应用程序使用次数(一)
- c# 使用独立的DLL来存储图片(资源文件)
- VC++下使用ADO编写数据库程序(关键文章)
- 在ADO.NET中使用参数化SQL语句访问不同数据库时的差异