[转]使用ADO实现vc中二进制文件数据的存取(以图像在数据库中的存取为例) ...
转自:http://home.kaoyan.com/home.php?mod=space&uid=2820987&do=blog&id=46560
实现方法
简述关键代码如下:
1、保存图片数据到数据库
以下是代码片段:
1. //JPG图片保存到数据库
2. try
3. {
4. _RecordsetPtr pRecordset;
5. pRecordset.CreateInstance(__uuidof(Recordset));
6. pRecordset->Open("SELECT * FROM jpg",_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);
7. pRecordset->AddNew();
8. pRecordset->Fields->Item["jpgid"]->Value = (_variant_t)m_JPGId;//jpgid
9. VARIANT pvList;
10. SetPictureToVariant(pvList,(unsigned char *)m_pJPGBuffer);
11. pRecordset->Fields->Item["jpgimage"]->AppendChunk(pvList); //JPG图像文件
12. VariantClear(&pvList);
13.
14. pRecordset->Update();
15. pRecordset->Close();
16. AfxMessageBox("JPG图像保存成功!");
17. m_JPGId == "";
18. UpdateData(false);
19. }
20. catch(...)
21. {
22. AfxMessageBox("数据库读取失败");
23. return;
24. }
其中SetPictureToVariant如下:
以下是代码片段:
1. void CBMPinDBDlg::SetPictureToVariant(VARIANT &pvList, unsigned char *sPicture)
2. {
3. SAFEARRAYBOUND saBound[1];
4. saBound[0].cElements = m_nFileLen;
5. saBound[0].lLbound = 0;
6. SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, saBound);
7. for (long l = 0; l < (long)m_nFileLen; l ++)
8. {
9. SafeArrayPutElement( pSA, &l, (void*)&sPicture[l]);
10. }
11. VariantClear(&pvList);
12. pvList.vt = VT_UI1 | VT_ARRAY;
13. pvList.parray = pSA;
14. }
2、从数据库读取图像文件并且显示在界面
以下是代码片段:
1. //从数据库里取JPG图像文件
2. try
3. {
4. _RecordsetPtr pRecordset;
5. char sSql[129];
6. sprintf(sSql,"SELECT *FROM jpg WHERE jpgid=’%s’",m_JPGId);
7. pRecordset.CreateInstance(__uuidof(Recordset));
8. pRecordset->Open(sSql,_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);
9. if (pRecordset->adoEOF)
10. {
11. CString str;
12. str.Format("没有JPGid为: %s 的JPG图像!",m_JPGId );
13. AfxMessageBox(str);
14. Invalidate();
15. m_JPGId = "";
16. UpdateData(false);
17. m_EidtJPGId.SetFocus();
18. return;
19. }
20. _variant_t pvList ;
21. long lDataSize = pRecordset->GetFields()->GetItem("jpgimage")->ActualSize;
22. m_nFileLen = (DWORD)lDataSize;
23. if(lDataSize > 0)
24. {
25. _variant_t varBLOB;
26. varBLOB = pRecordset->GetFields()->GetItem("jpgimage")->GetChunk(lDataSize);
27. //把二进制格式的图片转为图片格式
28. try
29. {
30. if(varBLOB.vt == (VT_ARRAY | VT_UI1))
31. {
32. if(m_pJPGBuffer = new char[lDataSize+1])
33. {
34. char *pBuf = NULL;
35. SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
36. memcpy(m_pJPGBuffer,pBuf,lDataSize);
37. SafeArrayUnaccessData (varBLOB.parray);
38. m_nFileLen = lDataSize;
39.
40. //m_pJPGBuffer -> pPicture
41. HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen );
42. LPVOID lpBuf = ::GlobalLock( hMem );
43. memcpy(lpBuf,m_pJPGBuffer,m_nFileLen);
44.
45. ::GlobalUnlock( hMem );
46.
47. if ( CreateStreamOnHGlobal( hMem, TRUE, &pStream ) !=S_OK )
48. return ;
49.
50. if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&pPicture ) !=S_OK )
51. return ;
52.
53. Invalidate();//在界面显示
54. }
55. }
56. }
57. catch(...)
58. {
59. AfxMessageBox("从数据库中读取jpg图像有错!");
60. return;
61. }
62.
63. }
64.
65. }
66. catch(...)
67. {
68. AfxMessageBox("数据库读取失败");
69. return;
70. }