IFilter接口,如何提取二进制流中的文本?求助高手!

zhangxue 2005-09-16 10:44:54
IFilter可以轻松提取磁盘文件中的文本,如office系列文档,但如果不是磁盘文件,例如将文档二进制数据存入了数据库,能否直接对这个二进制流进行文本提取。
下面是我写的一个函数,其中BindIFilterFromStream()无法定位一个正确的IFilter,请高手帮助解决,非常感谢!!!

/*!
* \brief 通过转换器提取指定字节流的文本
* \param[in] *pStream 字节流,如office文档二进制内容
* \param[in] nStreamSize 字节流的字节数
* \return LPCTSTR 返回的文本内容, NULL 失败
* \author zhangxue
* \date 2005-9-14 16:50:19
* \remarks 获得的文本指针使用完后必须用FreeText()关闭
*/
LPCTSTR CHLFilter::GetText(void *pStream, long nStreamSize)
{
LPTSTR lpszRetval = NULL;
if(!pStream || nStreamSize <= 0)
{
return lpszRetval;
}

_AFX_THREAD_STATE* pState = AfxGetThreadState();
if(!pState->m_bNeedTerm)
{
AfxOleInit();
}

IStream* pIStream;
HRESULT hr;
hr = CreateStreamOnHGlobal(0, TRUE, &pIStream);
if(FAILED(hr))
return lpszRetval;

ULONG lBytesWritten;
hr = pIStream->Write(pStream, nStreamSize, &lBytesWritten);

pIStream->AddRef();

if(FAILED(hr))
return lpszRetval;

LPUNKNOWN pUnkOuter;
LPUNKNOWN ppIUnk;
pUnkOuter = NULL;
ppIUnk = NULL;
hr = BindIFilterFromStream(pIStream, pUnkOuter, (void**)&ppIUnk);
if(FAILED(hr) || !ppIUnk)
{
return lpszRetval;
}

//开始提取文字
LPWSTR lpw = NULL;
IFilter * pFilter;
ULONG uFlag;
ULONG uLen;
SCODE sCode;
STAT_CHUNK sStat;
if(ppIUnk)
{
int iLength = 0;
//2004-12-24 modified by zhangxue 防止堆栈溢出
//WCHAR chunk[MAXLENGTH];
WCHAR *chunk = new WCHAR[MAXLENGTH];
memset(chunk, 0, MAXLENGTH * sizeof(WCHAR));

ppIUnk->QueryInterface(IID_IFilter,(void**)&pFilter);
sCode = pFilter->Init(0, 0, 0, &uFlag);
sCode = pFilter->GetChunk(&sStat);
int iTimes = 0;
while(sCode == S_OK && iTimes < MAXTIMES)
{
while(sCode == S_OK)
{
uLen = MAXLENGTH;
memset(chunk, 0, MAXLENGTH * sizeof(WCHAR));
sCode = pFilter->GetText(&uLen, chunk);
size_t iCheckLen = wcslen(chunk);
if(uLen > 0 && iCheckLen > 0)
{
for(int iIndex = 0; iIndex < (int)iCheckLen; iIndex++)
{
if(chunk[iIndex] == 0x00a0)
chunk[iIndex] = 0x0020;
}
iLength += iCheckLen;
LPWSTR pstrNewString = (LPWSTR)new WCHAR[(iLength + 1) * sizeof(WCHAR)];
memset (pstrNewString, 0, (iLength + 1) * sizeof(WCHAR));
if(lpw)
{
wcscpy(pstrNewString, lpw);
}
wcscat(pstrNewString, chunk);
if(lpw)
{
delete[] lpw;
lpw = NULL;
}
lpw = pstrNewString;
}
}
sCode = pFilter->GetChunk(&sStat);
iTimes ++;
}
if(chunk)
{
delete[] chunk;
chunk = NULL;
}
if(ppIUnk)
{
ppIUnk->Release();
ppIUnk = NULL;
}
if(pFilter)
{
pFilter->Release();
pFilter = NULL;
}
}

if(pIStream)
{
pIStream->Release();
pIStream = NULL;
}

if(lpw)
{
#ifdef _UNICODE
lpszRetval = lpw;
#else
UnicodeToGB(LPCTSTR(lpw), wcslen(lpw) * sizeof(WCHAR), (LPSTR)lpszRetval,0);
delete lpw;
lpw = NULL;
#endif
}
return lpszRetval;
}
...全文
106 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangxue 2005-09-28
  • 打赏
  • 举报
回复
高手们,救救我吧!
wg88888 2005-09-19
  • 打赏
  • 举报
回复
关注
zhangxue 2005-09-19
  • 打赏
  • 举报
回复
呜呜~~~每人理我!!!

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧