Partager via


ILockBytes::ReadAt

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_INTEGER ulOffset,   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 retournée

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.

Exemple

// Declarations
HRESULT            hr;
DBBINDING          rgBindings[1];
DBPROP             dbprop[1];
DBPROPSET          dbpropset[1];
DBOBJECT           dbObject;
BYTE               pData[100];    //buffer for holding the ILockBytes pointer
HROW               rghRows[1]; // Array of row handles obtained from the rowset object
HROW               *prghRows           = rghRows;
BYTE               pBuffer[1000];  //Buffer for holding a chunck of BLOB data
ULARGE_INTEGER     ulOffset;
ULONG              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_3_0, 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 the 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 the query syntax.
// We know that 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(ULONG);
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 less 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, then release the ILockBytes pointer and 
// row handle here

Exit: 

// When finished, clear the properties arrays and release interfaces.
// Uninitialize the environment.

return;

Voir aussi

Référence

ILockBytes::SetSize
ILockBytes::Stat
ILockBytes::WriteAt

Autres ressources

ILockBytes (SQL Server Compact Edition)

Aide et information

Assistance sur SQL Server Compact Edition