将 ADO 记录集保存到一个 IStream
ADO 1.5 x 和 2.x Recordset 实施提供了用于数据持久性到磁盘文件的两个函数:
若要将保存到文件中记录集对象 ADORecordset.Save()。
重新加载一个文件中的记录集 ADORecordset.Open()。
出于性能或其他原因它可能有时是所希望将 ADO 记录集保存到内存中,只能作为数据的流。若要完成的您可以使用 ADO 记录集的 IPersistStream 接口实现。
保存一个 ADO 记录集对象
此示例使用以下步骤来保存一个 ADO 记录集:
在给定的 ADO 记录集,获取一个指针到 IPersistStream 对象上调用 QueryInterface()。
若要创建一个标准,COM,IStream 对象使用 CreateStreamOnHGlobal()。
调用 COM 函数 OleSaveToStream() 将 IPersistStream 对象保存到 IStream 对象。
重新创建 ADO 记录集
重新指定 IStream 对象,该示例然后创建另一个 ADO 记录集从它。它执行此使用保存的数据流并调用 OleLoadFromStream() IStream 指针。
下面是键的代码示例中:
int main(int argc, char* argv[])
{
InitOle oleinit;
HRESULT hr=S_OK;
_RecordsetPtr rs; //Recordset for Saving Data
_RecordsetPtr rs2; //Recordset for Loading Data
IStreamPtr pStream;
//----------------------------------------
// Create a recordset for testing
//----------------------------------------
if (FAILED(CreateTestRS(&rs)))
{
printf("Couldn't create the first recordset\n");
goto exit;
}
//----------------------------------------
// Create IStream
//----------------------------------------
if (FAILED(SaveRS(rs, (IStream**)&pStream)))
{
printf("Couldn't save the recordset\n");
goto exit;
}
//----------------------------------------
// Load another recordset from IStream
//----------------------------------------
if (FAILED(LoadRS(&rs2, pStream)))
{
printf("Couldn't save the recordset\n");
goto exit;
}
//Now display the names of the fields of the rs that we just recreated
{
for (short i =0;iFields->Count;i++)
printf("Name of field %d is %s\n", i, (LPCTSTR) rs2->Fields->GetItem(i)->Name);
}
//----------------------------------------
// Pause and then exit so that the user
// Can
//----------------------------------------
exit:
printf("Press any key to end program\n");
_getch();
return 0;
}
//----------------------------------------
// Create a recordset from scratch
//----------------------------------------
HRESULT CreateTestRS(_Recordset** prs)
{
try
{
* prs=NULL;
_RecordsetPtr pRS;
pRS.CreateInstance( __uuidof(Recordset));
pRS->CursorLocation = adUseClient;
pRS->CursorType = adOpenStatic;
pRS->LockType = adLockBatchOptimistic;
// append fields
pRS->Fields->Append(_bstr_t("ADOField1"), adVarChar, 45,adFldFixed);
pRS->Fields->Append(_bstr_t("ADOField2"), adBoolean, 0,adFldFixed);
pRS->Fields->Append(_bstr_t("ADOField3"), adCurrency, 0,adFldFixed);
pRS->Fields->Append(_bstr_t("ADOField4"), adDate, 0,adFldFixed);
pRS->Open(vtMissing, vtMissing, adOpenStatic,adLockBatchOptimistic,-1);
*prs= pRS.Detach();
}
catch (_com_error & e)
{
return e.Error();
}
return S_OK;
}
HRESULT SaveRS(_RecordsetPtr pRS, IStream* * ppStream)
{
HRESULT hr=S_OK;
try
{
*ppStream=NULL;
// QI and return IPersistStream
IPersistStreamPtr pIPersist(pRS);
if (pIPersist )
{
//Create a standard stream in memory
if (FAILED(hr=CreateStreamOnHGlobal(0, TRUE, (IStream **)ppStream)))
return hr;
// Persist the pRS
if (FAILED(hr=OleSaveToStream(pIPersist, *ppStream)))
return hr;
}
else
return E_NOINTERFACE;
}
catch (_com_error & e)
{
return e.Error();
}
return S_OK;
}
HRESULT LoadRS(_Recordset* *ppRS, IStreamPtr pStream)
{
HRESULT hr=S_OK;
try
{
*ppRS=NULL;
if (NULL==pStream)
return E_NOINTERFACE;
// Load the pRS.
LARGE_INTEGER li;
li.QuadPart = 0;
//Set the pointer to the beginning of the stream
if (FAILED(hr=pStream->Seek(li, STREAM_SEEK_SET, 0)))
return hr;
if (FAILED(hr=OleLoadFromStream(pStream,
__uuidof(_Recordset),
reinterpret_cast(ppRS)))
)
return hr;
}
catch (_com_error & e)
{
return e.Error();
}
return S_OK;
}
_StreamPtr pStreamTest = NULL;
_bstr_t strPath("D:/1.txt");
_bstr_t strOpen("");
_variant_t varBLOB;
_variant_t varOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
HRESULT hr = pStreamTest.CreateInstance(__uuidof(Stream));
if(FAILED(hr))
{
return;
}
pStreamTest->Type = adTypeBinary;
hr = pStreamTest->Open(varOptional, adModeUnknown, adOpenStreamUnspecified, strOpen, strOpen);
mm->Save(pStreamTest.GetInterfacePtr(), adPersistADTG);
pStreamTest->SaveToFile("d:\\1.txt", adSaveCreateOverWrite);
//pStreamTest->put_Position(0);
//pStreamTest->LoadFromFile(strPath);
/*pStreamTest->WriteText("adsf", adWriteChar);*/
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, pStreamTest->GetSize());
LPVOID pvData = NULL;
IStream *ps;
//CString s = pStreamTest->ReadText(adReadAll);
//MessageBox(s);
varBLOB = pStreamTest->Read(adReadAll);
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
int aa = pStreamTest->GetSize() + 1;
//char * m_pBMPBuffer = new char[pStreamTest->GetSize() + 1];//分配必要的存储空间
char *pBuf = NULL;
HRESULT hr1 =SafeArrayAccessData(varBLOB.parray, (void **)&pBuf);
memcpy(pvData, pBuf, pStreamTest->GetSize()); //复制数据到缓冲 区 m_pBMPBuffer
SafeArrayUnaccessData(varBLOB.parray);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal, TRUE, &ps);
}
}