ILockBytes::ReadAt

ReadAt 은 바이트 배열 시작 부분의 지정된 오프셋부터 지정된 수만큼의 바이트를 읽습니다.

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

매개 변수

설명

ulOffset [in]

바이트 배열의 시작 부분에서 데이터를 읽기 시작할 지점을 지정합니다.

pv [in]

바이트 배열을 읽어 들일 버퍼에 대한 포인터입니다.

cb [in]

바이트 배열에서 읽어 들일 데이터의 바이트 수를 지정합니다.

pcbRead [out]

이 메서드가 바이트 배열에서 읽어 들인 실제 바이트 수를 기록할 위치에 대한 포인터입니다. 이 포인터를 NULL로 설정하여 이 값을 사용하지 않을 수도 있습니다. 이 경우 이 메서드는 읽어 들인 실제 바이트 수를 제공하지 않습니다.

용어

정의

NOERROR

메서드가 성공했습니다.

E_UNEXPECTED

행 집합이 "좀비" 상태에 있습니다.

STG_E_INVALIDPOINTER

전달된 포인터가 유효하지 않습니다.

다음 예는 ILockBytes::ReadAt 메서드를 사용하여 BLOB(Binary Large Object) 데이터를 검색하는 방법을 보여 줍니다. 이 예는 Employees 테이블의 "Photo" 열에서 이미지 데이터를 읽습니다.

다음 예는 32비트 플랫폼과 64비트 플랫폼 모두에 대해 업데이트되었습니다. 64비트의 호환 가능한 유형은 sqlce_oledb.h 네이티브 헤더 파일에서 가져온 것입니다. %ProgramFiles%\Microsoft SQL Server Compact Edition\v3.5\Include 폴더에서 sqlce_oledb.h 네이티브 헤더 파일을 찾을 수 있습니다. 자세한 내용은 Microsoft 웹 사이트에서 OLE DB Programmer's Guide의 OLE DB 64비트 정보 항목을 참조하십시오.

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


표시: