如何使用TComInterface 对象并将其读入TMemoryStream?我是否可以使用TComInterface 并将其用作TStream *以某种方式使用TMemoryStream LoadFromStream调用?
最佳答案
一种方法是Read()
将IStream
数据放入缓冲区,然后将Write()
移至TMemoryStream
,例如:
TComInterface<IStream> pIStrm;
TMemoryStream *pMStrm;
...
STATSTG stat = {0};
OleCheck(pIStrm->Stat(&stat, STATFLAG_NONAME));
LARGE_INTEGER li;
li.QuadPart = 0;
ULARGE_INTEGER ul;
OleCheck(pIStrm->Seek(li, STREAM_SEEK_CUR, &ul));
unsigned __int64 ulPos = ul.QuadPart;
BYTE buffer[1024];
while (ulPos < stat.cbSize.QuadPart)
{
ULONG ulRead;
OleCheck(pIStrm->Read(buffer, min(stat.cbSize.QuadPart - ulPos, sizeof(buffer)), &ulRead));
pMStrm->WriteBuffer(buffer, ulRead);
ulPos += ulRead;
}
...
另一个选择是编写一个
TStream
派生的类,该类在内部访问IStream
(类似于RTL的TStreamAdapter
类包装TStream
以便可以作为IStream
传递)的方式,例如:class TIStreamWrapper : public TStream
{
private:
TComInterface<IStream> pIStrm;
protected:
virtual __int64 __fastcall GetSize();
virtual void __fastcall SetSize(const __int64 NewSize);
public:
__fastcall TIStreamWrapper(IStream *Strm);
virtual int __fastcall Read(void *Buffer, int Count);
virtual int __fastcall Write(const void *Buffer, int Count);
virtual __int64 __fastcall Seek(const __int64 Offset, TSeekOrigin Origin);
};
__fastcall TIStreamWrapper::TIStreamWrapper(IStream *Strm)
: pIStrm(Strm, true)
{
}
__int64 __fastcall TIStreamWrapper::GetSize()
{
STATSTG stat = {0};
OleCheck(pIStrm->Stat(&stat, STATFLAG_NONAME));
return stat.cbSize.QuadPart;
}
void __fastcall TIStreamWrapper::SetSize(const __int64 NewSize)
{
ULARGE_INTEGER ul;
ul.QuadPart = NewSize;
OleCheck(pIStrm->SetSize(ul));
}
int __fastcall TIStreamWrapper::Read(void *Buffer, int Count)
{
ULONG ulRead;
OleCheck(pIStrm->Read(Buffer, Count, &ulRead));
return ulRead;
}
int __fastcall TIStreamWrapper::Write(const void *Buffer, int Count)
{
ULONG ulWritten;
OleCheck(pIStrm->Write(Buffer, Count, &ulWritten));
return ulWritten;
}
static const DWORD IStreamSeekOrigin[] = {STREAM_SEEK_SET, STREAM_SEEK_CUR, STREAM_SEEK_END};
__int64 __fastcall TIStreamWrapper::Seek(const __int64 Offset, TSeekOrigin Origin)
{
LARGE_INTEGER li;
li.QuadPart = Offset;
ULARGE_INTEGER ul;
OleCheck(pIStrm->Seek(li, IStreamSeekOrigin[Origin], &ul));
return ul.QuadPart;
}
TComInterface<IStream> pIStrm;
TMemoryStream *pMStrm;
...
TIStreamWrapper *pWrapper = new TIStreamWrapper(pIStrm);
try
{
pMStrm->LoadFromStream(pWrapper);
// or: pMStrm->CopyFrom(pWrapper, 0);
}
__finally
{
delete pWrapper;
}
...
关于delphi - 如何将IStream加载到TMemoryStream中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15441014/