功能:
需要将多种格式的文件保存到SQL server数据库中,例如:.dxf/bmp/jpg/doc等等。
在需要时,将保存的文件从数据库中读取回来,并按照原来格式写回到本地硬盘上,供程序使用。参照http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=18143的例子改写。
在SQL Server 2K中将文件数据的字段设置为image类型。问题:
已经将文件写入数据库中,但是读取文件后,文件大小与原文件一致,但是里面数据却不正常。

解决方案 »

  1.   

    附:写入例子
    CString fileName="ASPHALT.bmp";
    _bstr_t strCnn("Driver={SQL Server};Server=127.0.0.1;Database=subway;Uid=subway_admin;Pwd=admin;");  CFile imagefile;
    if(0 == imagefile.Open(fileName,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;

    try
    {
    AfxOleInit(); //Open a connection
    pConnection.CreateInstance(__uuidof(Connection));
    hr = pConnection->Open(strCnn,"","",NULL); //Connect a DataBase
    pRs.CreateInstance(__uuidof(Recordset));
    pRs->Open("dxf_file",_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdTable); //Open a Table pRs->AddNew(); 
    pRs->PutCollect("filename",_variant_t("测试文件名称"));  

    pRs->Fields->GetItem("filedata")->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.   

    附读取代码:
    _RecordsetPtr pRs = NULL;
    _ConnectionPtr pConnection = NULL;
    _variant_t varChunk;

    HRESULT hr;
    VARIANT varBLOB;
    _bstr_t strCnn("Driver={SQL Server};Server=127.0.0.1;Database=subway;Uid=subway_admin;Pwd=admin;"); 
    try
    {
    //Open a connection
    AfxOleInit(); pConnection.CreateInstance(__uuidof(Connection));
    hr = pConnection->Open(strCnn,"","",NULL); 
    pRs.CreateInstance(__uuidof(Recordset));
    pRs->Open("dxf_file",_variant_t((IDispatch *) pConnection,true),adOpenKeyset,adLockOptimistic,adCmdTable);
    //read data 
    long lDataLength = pRs->Fields->GetItem("filedata")->ActualSize;
    varBLOB = pRs->GetFields()->GetItem("filedata")->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 = "F:\\ASPHALT_1.bmp";
    //strFileName = tmpPath+strFileName;

    CFile outFile(strFileName,CFile::modeCreate|CFile::modeWrite);
    LPSTR buffer = (LPSTR)GlobalLock((HGLOBAL)pBuf);

    //outFile.WriteHuge(buffer,lDataLength);
    outFile.Write(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); 
    }