Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
ReadAt lit un nombre spécifique d'octets à partir d'un décalage donné par rapport au début du tableau d'octets.
Syntaxe
HRESULT ReadAt(
ULARGE_INTEGERulOffset,
void *pv,
ULONG cb,
ULONG *pcbRead
);
Paramètres
Paramètre |
Description |
|---|---|
ulOffset [in] |
Spécifie le point de départ de la lecture des données par rapport au début du tableau d'octets. |
pv [in] |
Pointeur vers le tampon dans lequel le tableau d'octets est lu. |
cb [in] |
Spécifie le nombre d'octets de données à lire à partir du tableau d'octets. |
pcbRead [out] |
Pointeur vers l'emplacement auquel cette méthode écrit le nombre réel d'octets lus à partir du tableau d'octets. Vous pouvez attribuer à ce pointeur la valeur NULL pour indiquer que ce paramètre ne vous intéresse pas. Dans ce cas, cette méthode ne communique pas le nombre réel d'octets lus. |
Valeur de retour
Terme |
Définition |
|---|---|
NOERROR |
La méthode a réussi. |
E_UNEXPECTED |
L'ensemble de lignes est à l'état zombie. |
STG_E_INVALIDPOINTER |
Un pointeur transmis n'est pas valide. |
Notes
L'exemple suivant montre comment utiliser la méthode ILockBytes::ReadAt pour extraire des données d'objet BLOB (binary large object). Cet exemple lit des données image dans la colonne « Photo » de la table Employees.
L'exemple suivant a été mis à jour pour les plateformes 32 bits et 64 bits. Les types compatibles 64 bits proviennent du fichier d'en-tête natif sqlce_oledb.h. Le fichier d'en-tête natif sqlce_oledb.h est disponible dans le dossier %ProgramFiles%\Microsoft SQL Server Compact Edition\v3.5\Include. Pour plus d'informations, consultez la rubrique d'informations sur OLE DB 64 bits dans le Guide du Programmeur OLE DB sur le site Web Microsoft.
Exemple
// Declarations
HRESULT hr;
DBBINDING rgBindings[1];
DBPROP dbprop[1];
DBPROPSET dbpropset[1];
DBOBJECT dbObject;
BYTE pData[100]; // Buffer for holding ILockBytes pointer.
HROW rghRows[1]; // Array of row handles obtained from rowset object.
HROW *prghRows = rghRows;
BYTE pBuffer[1000]; // Buffer for holding a chunk of BLOB data.
ULARGE_INTEGER ulOffset;
DBROWCOUNT cRows = 0;
IDBInitialize *pIDBInitialize = NULL;
IDBProperties *pIDBProperties = NULL;
IDBCreateSession *pIDBCreateSession = NULL;
IDBCreateCommand *pIDBCreateCommand = NULL;
ICommandText *pICommandText = NULL;
IAccessor *pIAccessor = NULL;
IRowset *pIRowset = NULL;
ILockBytes *pILockBytes = NULL;
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
if (FAILED(hr = CoInitialize(NULL)))
{
return;
}
VariantInit(&dbprop[0].vValue);
// Create an instance of the OLE DB Provider.
hr = CoCreateInstance(CLSID_SQLSERVERCE, 0, CLSCTX_INPROC_SERVER,
IID_IDBInitialize, (void**)&pIDBInitialize);
if(FAILED(hr))
{
// Send error-specific message and do error handling.
goto Exit;
}
// Initialize a property with name of the database.
// Open an exsiting database myDatabase.
dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
dbprop[0].vValue.vt = VT_BSTR;
dbprop[0].vValue.bstrVal = SysAllocString(L"\\windows\\MyDB.sdf");
if(NULL == dbprop[0].vValue.bstrVal)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Initialize the property set.
dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
dbpropset[0].rgProperties = dbprop;
dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]);
// Set initialization properties.
hr = pIDBInitialize->QueryInterface(IID_IDBProperties,
(void **)&pIDBProperties);
if(FAILED(hr))
{
goto Exit;
}
// Sets properties in data source and initialization property groups.
hr = pIDBProperties->SetProperties(1, dbpropset);
if(FAILED(hr))
{
goto Exit;
}
// Initializes a data source object.
hr = pIDBInitialize->Initialize();
if(FAILED(hr))
{
goto Exit;
}
// Get the IDBCreateSession interface.
hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession,
(void**)&pIDBCreateSession);
if (FAILED(hr))
{
// Send error-specific message and do error handling.
goto Exit;
}
// Get the interface to create a command.
hr = pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand,
(IUnknown**) &pIDBCreateCommand);
if (FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Create the new command that uses parameters.
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &pICommandText);
if (FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Specify the command text using parameter markers in query syntax.
// This command will return 1 row and one image column (Photo).
hr = pICommandText->SetCommandText(DBGUID_DBSQL, L"SELECT Photo FROM Employees WHERE \"Employee ID\" = 2");
if (FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
hr = pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**) &pIRowset);
if(FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Create the acessor object and column specific bindings.
hr = pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
if (FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Create the bindings for the photo (BLOB) column.
dbObject.dwFlags = STGM_READ;
dbObject.iid = IID_ILockBytes;
rgBindings[0].iOrdinal = 1;
rgBindings[0].obStatus = 0;
rgBindings[0].obLength = rgBindings[0].obStatus + sizeof(DBSTATUS);
rgBindings[0].obValue = rgBindings[0].obLength + sizeof(DBLENGTH);
rgBindings[0].pTypeInfo = NULL;
rgBindings[0].pObject = &dbObject;
rgBindings[0].pBindExt = NULL;
rgBindings[0].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
rgBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
rgBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
rgBindings[0].cbMaxLen = sizeof(IUnknown*);
rgBindings[0].dwFlags = 0;
rgBindings[0].wType = DBTYPE_IUNKNOWN;
rgBindings[0].bPrecision = 0;
rgBindings[0].bScale = 0;
// Create accessor.
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, rgBindings,
0, &hAccessor, NULL);
if(FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Get the first row.
hr = pIRowset->GetNextRows(NULL, 0, 1, &cRows, &prghRows);
if(FAILED(hr) || (0 == cRows))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Get the ILockBytes pointer.
hr = pIRowset->GetData(rghRows[0], hAccessor, pData);
if(FAILED(hr))
{
// Send an error-specific message and do error handling.
goto Exit;
}
if(DBSTATUS_S_OK != *(DBSTATUS*)(pData + rgBindings[0].obStatus))
{
// Send an error-specific message and do error handling.
goto Exit;
}
// Get the ILockBytes pointer from the buffer.
pILockBytes = *(ILockBytes**)(pData + rgBindings[0].obValue);
// Initialize Offset.
ulOffset.QuadPart = 0;
// Retrieve data from the interface in chunks.
// The infinite loop for(;;) will terminate when the ReadAt call fails
// or if fewer bytes are returned than were requested.
for(;;)
{
ULONG cbRead;
// Read data at the specified offset.
hr = pILockBytes->ReadAt(ulOffset, pBuffer, sizeof(pBuffer)-sizeof(WCHAR),
&cbRead);
///////////////////////////////////////////////////////////////////////
// Do some useful things here with the chunks of data.
///////////////////////////////////////////////////////////////////////
if(cbRead < sizeof(pBuffer)-sizeof(WCHAR) || FAILED(hr)) break;
ulOffset.QuadPart += cbRead;
}
// If more rows need to be read, release the ILockBytes pointer
// and row handle here.
Exit:
// When finished, clear the properties arrays and release interfaces.
// Uninitialize the environment.
return;