SQL Server 2000Visual C++ 7.1DBAWindows 2000Windows XPSQL Server 2005中级开发Visual StudioSQL ServerSQLWindowsC++
使用 ADO 从数据库加载图像文件






4.74/5 (21投票s)
通过 ADO 将图像文件放入数据库并从中检索。
引言
将图像文件放入数据库并从中检索并非易事。 如果您想在互联网上查找此类示例,您会惊讶地发现没有 C++ 示例。 只有信息表明您必须使用 Safearray
、SetChunk
和 GetChunk
方法。
本文将展示如何通过 ADO 将图像文件放入数据库,以及如何检索它们。 通过此示例,您可以使用任何文件格式,例如 Word、Excel 等,而不仅仅是图像文件格式。
实现
该示例包含两种将图像文件放入数据库并从中检索的方法。 第一种方法从数据库检索数据,在临时目录中创建一个文件,并将数据放入创建的文件中。 参数 strImageName
是将创建的文件名。 第二个参数指示包含图像数据的 ADO 字段对象。
以下代码示例显示了实现
CString CADOImageDBDlg::GetImageFromADO(CString strImageName, FieldPtr pField) { //Creating temp file char tmpPath[_MAX_PATH+1]; GetTempPath(_MAX_PATH,tmpPath); strImageName.Insert(0,tmpPath); CFile outFile(strImageName, CFile::modeCreate|CFile::modeWrite); //Helper variable for retrieving image data unsigned char* lpData = NULL; long lngOffSet = 0; long lngSize=pField->ActualSize; const long ChunkSize=50; _variant_t varChunk; UCHAR chData; HRESULT hr; long lBytesCopied = 0; lpData=new unsigned char [lngSize]; //Retrieveing data from vararray while(lngOffSet < lngSize) { try { //Get 50 size long chunk from database varChunk = pField->GetChunk(ChunkSize); //putting chunk in to safe array for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++) { hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData); if(SUCCEEDED(hr)) { ((UCHAR*)lpData)[lBytesCopied] = chData; lBytesCopied++; } else break; } lngOffSet += ChunkSize; } catch(_com_error &e) { dump_com_error(e); return FALSE; } } // LPSTR buffer = (LPSTR)GlobalLock(lpData); // write data in to file outFile.Write(lpData,lngSize); // free reserved data GlobalUnlock(lpData); delete lpData; //Return full path file return strImageName; } bool CADOImageDBDlg::PutImageInADO(CString strFilePath,FieldPtr pFileData) { //Opent File CFile fileImage; CFileStatus fileStatus; fileImage.Open(strFilePath, CFile::modeRead); fileImage.GetStatus(fileStatus); //Alocating memory for data ULONG nBytes = (ULONG)fileStatus.m_size; HGLOBAL hGlobal = GlobalAlloc(GPTR,nBytes); LPVOID lpData = GlobalLock(hGlobal); //Putting data in to file fileImage.Read(lpData,nBytes); HRESULT hr; _variant_t varChunk; long lngOffset = 0; UCHAR chData; SAFEARRAY FAR *psa = NULL; SAFEARRAYBOUND rgsabound[1]; try { //Create a safe array to //store the array of BYTES rgsabound[0].lLbound = 0; rgsabound[0].cElements = nBytes; psa = SafeArrayCreate(VT_UI1,1,rgsabound); while(lngOffset < (long)nBytes) { chData = ((UCHAR*)lpData)[lngOffset]; hr = SafeArrayPutElement(psa, &lngOffset, &chData); if(hr!=S_OK) return false; lngOffset++; } lngOffset = 0; //Assign the Safe array to a variant. varChunk.vt = VT_ARRAY|VT_UI1; varChunk.parray = psa; hr = pFileData->AppendChunk(varChunk); if(hr!=S_OK) return false; } catch(_com_error &e) { dump_com_error(e); return FALSE; } //Free memory GlobalUnlock(lpData); return true; }
为了图像显示,我创建了一个包装 freeimage 库的类。
更新历史
- 1.0.0.119 - 2006 年 1 月 27 日 - 第一个发布版本。