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