zoukankan      html  css  js  c++  java
  • 盘古分词修改支持mono和lucene.net3.03

    盘古分词平台兼容性

    在使用Lucece.net,需要一个中文的分词组件,比较好的是盘古分词,但是我希望能够在mono的环境下运行,就使用moma检查了一下盘古分词

    Assembly Version Missing Not Implemented Todo P/Invoke
    PanGu.dll 2.3.1.0 3 0 5 0
    Calling Method Method Missing from Mono
    WordInfo> PreSegment (string) string Strings.StrConv (string, VbStrConv, int)
    WordInfo> PreSegment (string) string Strings.StrConv (string, VbStrConv, int)
    WordInfo> PreSegment (string) string Strings.StrConv (string, VbStrConv, int)
    Calling Method Method with [MonoTodo] Reason
    string ReadFileToString (string, Encoding) int Marshal.GetHRForException (Exception) SetErrorInfo
    MemoryStream ReadFileToStream (string) int Marshal.GetHRForException (Exception) SetErrorInfo
    void WriteStream (string, MemoryStream) int Marshal.GetHRForException (Exception) SetErrorInfo
    void WriteLine (string, string) int Marshal.GetHRForException (Exception) SetErrorInfo
    void WriteString (string, string, Encoding) int Marshal.GetHRForException (Exception) SetErrorInfo

    1. 是StrConv这个函数没有检查通过,发现作者使用了 Microsoft.VisualBasic.Strings.StrConv 这个类库来处理简体和繁体转换的问题,这个类用到了windows平台的特性,所以没有编译通过,于是写了个简单的简体繁体转换的类库:简体中文与繁体相互转换.

    2. 是一个Marshal.GetHRForException 用来做io处理出错的时候判断的,代码如下大概是出现了ERR_PROCESS_CANNOT_ACCESS_FILE错误时让线程稍等。代码如下

      uint hResult = (uint)System.Runtime.InteropServices.Marshal.GetHRForException(e);
      if (hResult == ERR_PROCESS_CANNOT_ACCESS_FILE)
      {
      if (times > 10)
      {
      //Maybe another program has some trouble with file
      //We must exit now
      throw e;
      }

       System.Threading.Thread.Sleep(200);
       times++;
      

      }
      else
      {
      throw e;
      }

    查找MSDN在Marshal,如何:映射 HRESULT 和异常 里面有一句话 :

    COM 方法通过返回 HRESULT 来报告错误;.NET 方法则通过引发异常来报告错误。 运行时将处理这两者之间的转换。 .NET Framework 中的每个异常类都会映射到一个 HRESULT。

    也就是说HRESULT是给com来报告错误的,.net本身通过引发异常来处理错误,而这个IOException对应出来的hresult是

    文件“xxxx”正由另一进程使用,因此该进程无法访问此文件。

    但是引起这个错误的异常根源就是IOException,内部有个私有的HResult无法访问。只能修改为所有的错都等待10次,10次之后抛出异常,所以把外面的if之外的代码都注释掉变成

    if (times > 10)
    {
        //Maybe another program has some trouble with file
        //We must exit now
        throw e;
    }
    
    System.Threading.Thread.Sleep(200);
    times++;
    

    这样两个不兼容的问题就解决了。

    盘古分词Lucene3.03支持

    现在盘古分词给出的Lucene的示例是2.x的版本,而我希望能够用3.0的版本来集成,其中的区别是PanGuTokenizer.cs里面集成的时候会提示Next()方法没有找到合适的类来重写。原因是lucene中next()方法已改成incrementToken()方法.lucene的文档:

    This method is called for every token of a document, so an efficient implementation is crucial for good performance. To avoid calls to AttributeSource.addAttribute(Class) and AttributeSource.getAttribute(Class), references to all AttributeImpls that this stream uses should be retrieved during instantiation.

    所以只需要修改这个方法,改为使用addAttribute来实现:
    这里有一个已经修改好了的pangu分词的版本https://github.com/JimLiu/Lucene.Net.Analysis.PanGu .主要代码如下,其中next还是原来的方法,去掉override.

    添加属性

    private ITermAttribute termAtt;
    private IOffsetAttribute offsetAtt;
    private IPositionIncrementAttribute posIncrAtt;
    private ITypeAttribute typeAtt;
    
    termAtt = AddAttribute<ITermAttribute>();
    offsetAtt = AddAttribute<IOffsetAttribute>();
    posIncrAtt = AddAttribute<IPositionIncrementAttribute>();
    typeAtt = AddAttribute<ITypeAttribute>();
    

    方法实现

    public override bool IncrementToken()
    {
        ClearAttributes();
        Token word = Next();
        if (word != null)
        {
            termAtt.SetTermBuffer(word.Term);
            offsetAtt.SetOffset(word.StartOffset, word.EndOffset);
            typeAtt.Type = word.Type;
            return true;
        }
        End();
        return false;
    }
    

    以上就是让lucene.net在mono下使用盘古分词出现的一些问题。

  • 相关阅读:
    面向对象类成员之静态字段
    面向对象中,用super来联系父类的函数
    登录
    奇数偶数
    vue中播放音乐
    vue中的轮播图
    vue中的bind
    vue中的for
    django rest_framework中的APIView,ModelViewSet,认证,权限,频率,版本
    django rest_framework中的mixins,generics,ModelViewSet中的url简写
  • 原文地址:https://www.cnblogs.com/ac1985482/p/3634598.html
Copyright © 2011-2022 走看看