Accessing Item Streams

Topic Last Modified: 2009-07-27

You can get an item's stream by using a Record or Recordset object's Fields collection. To request the stream, pass the index value of -1 adDefaultStream to the Fields.Item method.

When using Collaboration Data Objects (CDO), you must use the CDO object's GetStream Method (IItem). You cannot retrieve the stream using the Fields collection.

Items that are collections, such as folders, do not have streams. Requesting the stream for these types of items causes an exception to be raised.

In the following example, the function receives a URL to an inbox item, gets the item's stream, and saves it to a file on disk.

VBScript

<job id="getstream">
<reference object="adodb.record"/>
<script language="vbscript">


Dim Stm
Dim Conn
Dim InfoNT
Dim sUrl
Dim sRelPath
Set InfoNT = CreateObject("WinNTSystemInfo")

sRelPath = "/public/test_folder/item4.txt"
sUrl = "http://" & InfoNT.Computername & sRelPath
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sUrl

Set Stm = getStream(sUrl, Conn)

If Stm.Type = adTypeText Then
  Wscript.echo Stm.ReadText
End If

' Close connection.
Conn.Close

' ...


'''''''''''''''''''''''''''''''''''''''
' getStream
'   sUrl - URL to item
'   Conn - Active Connection or Nothing
'
'''''''''''''''''''''''''''''''''''''''
Function getStream( sUrl, Conn)

 Dim Rec
 Dim Flds
 Dim sContentType

 Set Rec    = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 ' Try to open the item

 Rec.Open sUrl, Conn, adModeReadWrite
 Set Flds = Rec.Fields
 If Flds("DAV:isfolder") = True Or Flds("DAV:iscollection") = True Then
   Err.Raise &H80070057, "GetStream", "Item at URL is a collection."   ' E_INVALIDARG
 End If

 sContentType = flds("urn:schemas:mailheader:content-type")
 set stm = Flds(adDefaultStream).Value
 If Not sContentType = "" And InStr(sContentType, "text") > -1 Then
   Stm.Type = adTypeText
   If InStr(sContentType,"charset=") > -1 Then
    Stm.Charset = Mid(sContentType, InStr(sContentType, "charset=") + 8)
   End If
 End If

 Set getStream = Stm

End Function
</script>
</job>

Using C++

The following examples demonstrates how to use native OLE DB  interfaces in Microsoft® Visual C++® to write an item's stream and print an item's stream.

#include <oledb.h>

#include <msdasc.h>

#include <comdef.h>

#pragma comment(lib,"oledb.lib")

#pragma comment(lib,"msdasc.lib")

HRESULT writeItemStream( IRow* pRow, BYTE* pBytes, DWORD dwSize, ITransactionLocal* pTrans )

{

if(pRow == NULL || pBytes == NULL)

return E_INVALIDARG;

HRESULT hr = S_OK;

DWORD dwBindStatus = 0;

DWORD dwLevel = 0;

IStream* pStm = NULL;

ULONG cColumns = 1;

DBCOLUMNACCESS rgColumns[1];

VARIANT vStm;

if(pTrans != NULL) {

hr = pTrans->StartTransaction(ISOLATIONLEVEL_UNSPECIFIED,0,NULL,&dwLevel);

if(FAILED(hr))

return hr;

}

VariantInit(&vStm);

rgColumns[0].pData = &vStm;

rgColumns[0].columnid = DBROWCOL_DEFAULTSTREAM;

rgColumns[0].wType = DBTYPE_VARIANT;

rgColumns[0].cbDataLen = sizeof(VARIANT);

hr = pRow->GetColumns(cColumns, rgColumns);

if(FAILED(hr))

return hr;

hr = vStm.punkVal->QueryInterface(&pStm);

if(FAILED(hr)) {

VariantClear(&vStm);

return hr;

}

ULONG cbWritten = 0;

if( FAILED( hr = pStm->Write((void*)pBytes, dwSize, &cbWritten) ) ) {

VariantClear(&vStm);

return hr;

}

ULARGE_INTEGER uLargeInt;

uLargeInt.LowPart = dwSize;

uLargeInt.HighPart = 0;

if( FAILED(hr = pStm->SetSize(uLargeInt) ) ) {

VariantClear(&vStm);

return hr;

}

if(FAILED(hr = pStm->Commit(1)) ) {

VariantClear(&vStm);

return hr;

}

if(pTrans != NULL)

hr = pTrans->Commit(FALSE, 0 , 0);

VariantClear(&vStm);

return hr;

}

#include <oledb.h>

#include <msdasc.h>

#pragma comment(lib,"oledb.lib")

#pragma comment(lib,"msdasc.lib")

#include <stdio.h>

#define BUF_SIZE 4096

HRESULT printStream(BSTR itemURL) {

HRESULT hr = S_OK;

DWORD dwBindStatus = 0;

IBindResource* pBRes = NULL;

IStream* pStrm = NULL;

char* buf = new char[BUF_SIZE];

ULONG cbToRead = BUF_SIZE;

ULONG cbRead = 0;

CLSID clsid_ExOLEDBProviderBinder;

if(FAILED(hr = CLSIDFromProgID(L"ExOLEDB.Binder", &clsid_ExOLEDBProviderBinder)))

return hr;

if(itemURL == NULL)

return E_INVALIDARG;

hr = CoCreateInstance(

clsid_ExOLEDBProviderBinder,

NULL,

CLSCTX_INPROC_SERVER,

IID_IBindResource,

(void**)&pBRes);

if(FAILED(hr))

goto Exit;

hr = pBRes->Bind(

NULL,

itemURL,

DBBINDURLFLAG_READ,

DBGUID_STREAM,

IID_IStream,

NULL,

NULL,

&dwBindStatus,

(IUnknown**) &pStrm);

if(FAILED(hr))

goto Exit;

while(1) {

hr=pStrm->Read((void*)buf,cbToRead,&cbRead);

if(FAILED(hr)) {

goto Exit;

}

if(hr==S_FALSE || cbRead == 0)

break;

for(unsigned int i = 0;i<cbRead;i++)

printf("%c",buf[i]);

}

Exit:

delete [] buf;

if(pBRes)

pBRes->Release();

if(pStrm)

pStrm->Release();

return hr;

}