Freigeben über


ILockBytes::ReadAt

ReadAt liest eine angegebene Anzahl Bytes, wobei bei einem angegebenen Offset vom Anfang des Bytearrays begonnen wird.

Syntax

HRESULT ReadAt(   ULARGE_INTEGER ulOffset,   void *pv,   ULONG cb,   ULONG *pcbRead    );

Parameter

Parameter Beschreibung

ulOffset [in]

Gibt den Startpunkt vom Anfang des Bytearrays zum Lesen der Daten an.

pv [in]

Zeiger auf den Puffer, in den das Bytearray gelesen wird.

cb [in]

Gibt die Anzahl der Datenbytes an, die aus dem Bytearray gelesen werden sollen.

pcbRead [out]

Zeiger auf den Speicherort, wo diese Methode die tatsächliche Anzahl der aus dem Bytearray gelesenen Bytes schreiben wird. Sie können diesen Zeiger auf NULL festlegen, um anzugeben, dass Sie nicht an diesem Wert interessiert sind. In diesem Fall stellt diese Methode die tatsächliche Anzahl gelesener Bytes nicht bereit.

Rückgabewert

Term Definition

NOERROR

Die Methode wurde erfolgreich abgeschlossen.

E_UNEXPECTED

Das Rowset ist in einem veralteten Status.

STG_E_INVALIDPOINTER

Ein Zeiger, der übergeben wurde, ist ungültig.

Hinweise

Das folgende Beispiel zeigt, wie die ILockBytes::ReadAt-Methode verwendet wird, um BLOB-Daten (Binary Large Object) abzurufen. Dieses Beispiel liest Bilddaten aus der Fotospalte der Employees-Tabelle.

Beispiel

// 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;

Siehe auch

Referenz

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

Sonstige Ressourcen

ILockBytes (SQL Server Compact Edition)

Hilfe und Information

Informationsquellen für SQL Server Compact Edition