博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于用VC,VB进行图像数据(二进制大对象)存储数据库的一点心得
阅读量:3518 次
发布时间:2019-05-20

本文共 5481 字,大约阅读时间需要 18 分钟。

:

网上经常有人问如何把图像存入数据库中,原先我也是不得要领。经过多方指点和自己在开发过程中的摸索,终于解决这一问题。

       下面给出用VC,VB如何操作图像文件存取数据库的原码,帮助一些还没有掌握方法的朋友,也请这方面的高手多多指教。(均用ADO连接数据库)

1. VC把一个文件存入数据库

  CFile imagefile;

  if(0 == imagefile.Open("d://user//bmp.bmp",CFile::modeRead))
     return;
  _RecordsetPtr pRs = NULL;             
  _ConnectionPtr pConnection = NULL;
  _variant_t varChunk;
  HRESULT hr;
  BYTE* pbuf;
  long nLength = imagefile.GetLength();
  pbuf = new BYTE[nLength+2];
  if(pbuf == NULL)
     return;                             //allocate memory error;
  imagefile.Read(pbuf,nLength);          //read the file into memory

  BYTE *pBufEx;

  pBufEx = pbuf;
  //build a SAFFERRAY
  SAFEARRAY* psa;
  SAFEARRAYBOUND rgsabound[1];
  rgsabound[0].lLbound = 0;
  rgsabound[0].cElements = nLength;
  psa = SafeArrayCreate(VT_UI1, 1, rgsabound);

  for (long i = 0; i < nLength; i++)

       SafeArrayPutElement (psa, &i, pBufEx++);
  VARIANT varBLOB;
  varBLOB.vt = VT_ARRAY | VT_UI1;
  varBLOB.parray = psa;

  _bstr_t strCnn("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=CUSTOM;Data Source=SERVER");   

    try
    {
        //Open a connection
        pConnection.CreateInstance(__uuidof(Connection));
        hr = pConnection->Open(strCnn,"","",NULL);   //Connect a DataBase
        pRs.CreateInstance(__uuidof(Recordset));
        pRs->Open("CustomInfo",_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdTable);  //Open a Table
 
//      pRs->AddNew();       
        pRs->Fields->GetItem("Image")->AppendChunk(varBLOB);       
        pRs->Update();
        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("Source : %s /n Description : %s/n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
        AfxMessageBox(sError);    
 }

2. VC把数据库中IMAGE字段取出存为文件

    _RecordsetPtr pRs = NULL;

    _ConnectionPtr pConnection = NULL;
    _variant_t varChunk;
    HRESULT hr;
    VARIANT varBLOB;
    _bstr_t strCnn("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=CUSTOM;Data Source=SERVER");   
    try
    {
        //Open a connection
        pConnection.CreateInstance(__uuidof(Connection));
        hr = pConnection->Open(strCnn,"","",NULL);       
        pRs.CreateInstance(__uuidof(Recordset));
        pRs->Open("CustomInfo",_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdTable);
       //read  data  
       long lDataLength = pRs->Fields->GetItem("Image")->ActualSize;
       varBLOB = pRs->GetFields()->GetItem("Image")->GetChunk(lDataLength);
      if(varBLOB.vt == (VT_ARRAY | VT_UI1))       
     {
            BYTE *pBuf = NULL;   
            pBuf = (BYTE*)GlobalAlloc(GMEM_FIXED,lDataLength);
            SafeArrayAccessData(varBLOB.parray,(void **)pBuf); 
            //Build a File in Windows Temp Directory
            char tmpPath[_MAX_PATH+1];
            GetTempPath(_MAX_PATH,tmpPath);
            CString strFileName = "temp.bmp";
            strFileName = tmpPath+strFileName;
                                     
            CFile outFile(strFileName,CFile::modeCreate|CFile::modeWrite);
            LPSTR buffer = (LPSTR)GlobalLock((HGLOBAL)pBuf);
            outFile.WriteHuge(buffer,lDataLength);
            GlobalUnlock((HGLOBAL)pBuf);
            outFile.Close();          
            SafeArrayUnaccessData (varBLOB.parray);
       }

        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("Source : %s /n Description : %s/n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
        AfxMessageBox(sError);    
 } 

3. VB把文件存入数据库IMAGE字段

Sub savepic(FileName As String, IndexNumber As Long)

   Dim DcnNWind As New ADODB.Connection
   Dim rs As ADODB.Recordset
   Set rs = New ADODB.Recordset
   DcnNWind.CursorLocation = adUseClient
   DcnNWind.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=CUSTOM;Data Source=SERVER"
   rs.CursorType = adOpenKeyset
   rs.LockType = adLockOptimistic
   rs.Open "CustomInfo", DcnNWind, , adCmdTable
   rs.Move (IndexNumber)
   Call FileToBlob(rs.Fields("Image"), FileName, FileLen(FileName))
   rs.UpdateBatch adAffectCurrent
End Sub

Private Sub FileToBlob(fld As ADODB.Field, FileName As String, Optional ChunkSize As Long )

   Dim fnum As Integer, bytesLeft As Long, bytes As Long
   Dim tmp() As Byte
   If (fld.Attributes And adFldLong) = 0 Then
      Err.Raise 1001, , "Field doesn't support the GetChunk method."
   End If
   fnum = FreeFile
   Open FileName For Binary As fnum
      bytesLeft = LOF(fnum)
   Do While bytesLeft
      bytes = bytesLeft
      If bytes > ChunkSize Then bytes = ChunkSize
      ReDim tmp(1 To bytes) As Byte
      Get #1, , tmp
      fld.AppendChunk tmp
      bytesLeft = bytesLeft - bytes
   Loop
   Close #fnum
End Sub

4. VB把文件从IMAGE字段中读到文件中。

Sub loadpic(IndexNumber As Long)

   Dim DcnNWind As New ADODB.Connection
   Dim rs As ADODB.Recordset
   Set rs = New ADODB.Recordset
   DcnNWind.CursorLocation = adUseClient
   DcnNWind.Open "Provider=SQLOLEDB.1;Integrated Security=SSI;Persist Security Info=False;Initial Catalog=CUSTOM;Data Source=SERVER"
   rs.CursorType = adOpenKeyset
   rs.LockType = adLockOptimistic
   rs.Open "CustomInfo", DcnNWind, , adCmdTable
   rs.Move (IndexNumber)
   Call BlobToFile(rs.Fields("Image"), "c:/windows/temp/tmp.bmp", rs.Fields("Image").ActualSize)
End Sub

Private Sub BlobToFile(fld As ADODB.Field, FileName As String, Optional ChunkSize As Long )

   Dim fnum As Integer, bytesLeft As Long, bytes As Long
   Dim tmp() As Byte
   If (fld.Attributes And adFldLong) = 0 Then
      Err.Raise 1001, , "Field doesn't support the GetChunk method."
   End If
   If Dir$(FileName) <> "" Then Kill FileName
   fnum = FreeFile
   Open FileName For Binary As fnum
   bytesLeft = fld.ActualSize
   Do While bytesLeft
      bytes = bytesLeft
      If bytes > ChunkSize Then bytes = ChunkSize
      tmp = fld.GetChunk(bytes)
      Put #fnum, , tmp
      bytesLeft = bytesLeft - bytes
   Loop
   Close #fnum
End Sub

转载地址:http://noxqj.baihongyu.com/

你可能感兴趣的文章
将字符串 “k:1|k1:2|k2:3|k3:4” 转换成字典{“k”:1,”k1”:2,”k2”:3,”k3”:4}
查看>>
AttributeError: 'tuple' object has no attribute 'decode'
查看>>
node爬虫(牛刀小试)
查看>>
关于vue的seo优化
查看>>
字符串在html中的页面中的换行
查看>>
react父子组件间的通信和传值
查看>>
vue-cli3.0设置环境变量
查看>>
vue父组件直接操作子组件的方法(不通过$emit和$on)
查看>>
vue上传文件到UCloud
查看>>
获取input选择文件的本地地址
查看>>
React绑定全局方法或变量
查看>>
js监听div标签上面的自定义属性
查看>>
navcat如何重置窗口
查看>>
代码注入
查看>>
off-by-one
查看>>
ctf-pwn的一些小技巧
查看>>
POJ 1915 Knight Moves
查看>>
Git 撤销修改
查看>>
Git 删除文件
查看>>
Git与远程仓库关联以及关联错误解决方法
查看>>