Ifilter

什么是IFilter?
IFilter接口由微软设计,便于在索引服务中使用。主要为了从文件抽取文本,从而使索引服务能够索引及搜索。一些版本的windows本身实现了若干Office文件的IFilter接口,也有一些用于其他文件类型---比较流行的Adobe PDF 过滤器---免费和商用的过滤器。IFilter接口主要用于抽取文件的重要部分,像Office文档、PDF文档等非文本文件,但也用于HTML、XML等文本文件。虽然IFilter接口通常用作从文档抽取文本,但是它广泛应用于搜索引擎。Windows桌面搜索就使用过滤器索引文件。

另一些新东西
已经有许多关于如何在.NET中实现IFilter接口的文章和信息,或许你会问为什么还要写这篇文章?那些文章提到的实现方法存在一些问题,这促使我寻求一种不同的方法使用、载入过滤器。我在开发的新产品中使用,直到现在运行良好,故而决定和你分享---是的,和你!

实现概要
下面是我和其他人发现的概要,我接下来会详细讨论:
1.从大文件抽取文本
2.COM线程的问题
3.Adobe PDF 过滤器在关闭时使应用程序崩溃

从大文件抽取文本

在我找到的所有使用IFilter抽取文本并返回一个字符串的C#示例代码中都提供一个方法。通常,像如下写法:
public static string getTextFromFile(string path)
现在,或许可以满足一些用户,但是对于专门的索引,我觉得它不是最好的办法。一些文档非常大---30M的PDF或word文档并不罕见---一下抽取整个文本或许对垃圾回收器产生负面影响,既然这些对象将被存储在.NET的“大的对象堆”里。

COM线程的问题

过滤器本质上是COM 对象,所以他们带有一些让我们又爱又恨的COM线程模型问题。长话短说,一些过滤器标有STA(Adobe PDF filter),一些标有MTA(Microsoft XML filter),或两者皆有(Microsoft Office Filter)。这意味着MTA过滤器不能载入标有[STAThread]的C#线程,反之亦然。有人建议手动更改有问题的过滤器,但在产品安装时仍然存在一些你想不到的问题,由于你不清楚客户电脑上安装过哪种过滤器而带来的不可靠性。我们主要需要一种载入、使用过滤器的方法,不管是谁的线程模型。

Adobe PDF 过滤器在关闭时使应用程序崩溃

关于Adobe PDF过滤器的报道相当多。研究了一段时间,我认为我找到了问题所在。Adobe忘记(或许没有)了从他们的PDFFILT.dll导出DLLCanUnloadNow函数。既然一个过滤器实现了一个COM对象,它就应该导出这个函数以通知COM什么时候它能卸载这个库。这可能就是C#应用程序中问题的原因------这个dll从来没有被卸载,当真正去卸载时,为时已晚。

在我以前的应用程序版本中,我通过明确卸载PDFFILT.dll库以绕过该问题。现在,不必这样了。

我如何解决?

实现一个FilterReader
我决定克服困难,实现一个派生自FilterReader的类TextReader。这解决了问题1,因为我们不必一下子抽取整个文本。相反,你仅仅使用reader一次读取一个缓冲。如果你想得到作为一个字符串的整个文本,可以用ReadToEnd()方法。

绕过COM
要得到一个IFilter实例,你应调用LoadIFilter API,并传给他一个文件名。实际上,LoadIFilter最终调用CoCreateInstance()实例化过滤器,从而符合COM规则。为了避免线程问题,我决定绕过COM,实例化我自己的过滤器COM类。以下是介绍和设想:
1.我需要找到实现了某种特定文件类型的正确的COM类。
2.我需要动态载入实现了COM的dll,调用从dll导出的DllGetClassObject函数
3.我不想重新实现COM架构,因此为了卸载没用的COM dll,我决定在整个应用程序生命期内保留这些dll,仅在应用程序结束时卸载它们.注意,这解决了问题3,既然我们手动卸载PDFFILT.dll.
4.一个IFilter不应该被多个线程操控,既然他不再受COM保护.
5.我假定,当与COM无关时,一个STA过滤器在被MTA线程调用时,工作正常.直到现在,我没有碰到任何问题.如果你用此法遇到问题,请告知我.

总结
我们通过实现一个FilterReader解决问题1
通过绕过COM解决问题2和3

代码使用
这非常简单:
通过传递一个你要抽取文本的文件,实例化一个FilterReader,然后调用之,和任何TextReader的派生类一样。
TextReader reader=new FilterReader(fileName);
using (reader)
{
  textBox1.Text=reader.ReadToEnd();
}

以下部分略去

原文地址:http://www.codeproject.com/csharp/IFilter.asp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值