ICTCLAS2010的JNI调用实现过程

ICTCLAS2010的JNI调用实现过程


(2010-07-28 21:46:58)

ICTCLAS2010的JNI调用实现过程

JNI是Java Native Interface的缩写,中文为JAVA本地调用,详细信息可以看百度百科关于JNI的介绍:

http://baike.baidu.com/view/1272329.htm?fr=ala0_1_1

如果觉的这里JNI调用没有讲清楚的话,(因为我主要通过一个完整的案例来讲的,所以过于JNI的详细的教程没有!)可以看这个网址的教程,我开始学的时候看到的,还可以了,入门还行:

http://developer.51cto.com/art/200509/2815.htm

JNI调用一般步骤:

     以本讲解程序为例:

     1)首先这样一句话:

         static {

             System.loadLibrary("ICTCLAS2010");

         }

    引入dll文件(就是要背Java调用的文件,在Windows操作系统是dll文件,所以不需要些后缀名)

    2)然后根据接口文档(这个需要接口文档,如果是自己写的就应该知道),引入该dll中的需要的方法,并且都是native方法,只引入,不实现。

    格式如下:

    public native boolean ICTCLAS_Init(byte[] sPath);

    把这些写入一个类中。

    然后就可以在其他的类中调用这个类中的本地方法(native)了。

    准备工作当然要把dll文件放在项目文件夹下边。

    (其他的需要的配置文件,和一些文件也学要准备好!)

    现在开始实现ICTCLAS2010的调用:

     使用工具:Eclipse

     下载ICTCLAS2010-packet-release,这里提供一个新浪共享资料的下载地址:

      http://ishare.iask.sina.com.cn/f/7446738.html?from=dl

     将下载好的文件解压,里边有许多文件,待会儿要用。

    新建一个项目:

    将解压文件夹中的Data文件夹ICTCLAS2010.dll文件(就是我们需要调用的C++写的分词器了),ICTCLAS30.log文件(可以自己创建的,初始的时候是空的,是一个日志文件),Configure.xml配置文件(可以自己写,不过这里有现成的就直接拷过去了,然后根据自己的需要改改就好了),userdic.txt(用户词典文件,可以自己创建,然后再写代码的时候使用接口函数调用就可以了),还有一些其他的文件在这个程序里没有用到,所以不再说了!

    编写第一个类是JNI调用的类ICTCLAS2010.java:

 

package ICTCLAS.kevin.zhang;

public class ICTCLAS2010 {

   

    static {

       System.loadLibrary("ICTCLAS2010");

    }

   

    //初始化

    public native boolean ICTCLAS_Init(byte[] sPath);

    //退出

    public native boolean ICTCLAS_Exit();

    //导入用户词典

    public native int ICTCLAS_ImportUserDict(byte[] sPath);

    //获取uni概率

    public native float ICTCLAS_GetUniProb(byte[] sWord);

    //判断词典中有没有这个词

    public native boolean ICTCLAS_IsWord(byte[] sWord);

    //一段文字的分词

    public native byte[] ICTCLAS_ParagraphProcess(byte[] sSrc, int bPOSTagged);

    //一个文本文件的分词

    public native boolean ICTCLAS_FileProcess(byte[] sSrcFilename,

           byte[] sDestFilename, int bPOSTagged);

    public native byte[] nativeProcAPara(byte[] src);

    public native int ICTCLAS_AddUserWord(byte[] sWord);

    public native int ICTCLAS_SaveTheUsrDic();

    public native int ICTCLAS_DelUsrWord(byte[] sWord);

    public native int ICTCLAS_KeyWord(byte[] resultKey, int nCountKey);

    public native long ICTCLAS_FingerPrint();

    public native int ICTCLAS_SetPOSmap(int nPOSmap);

    public native int ICTCLAS_GetElemLength(int nIndex);

 

}

上边调用的这些本地(native)方法,在接口文档(刚才下载的文件夹下的“文档“文件夹下边有个ICTCLAS2010接口文档.doc文件)中都是有详细介绍的,我的博文中也做了一些介绍,主要做翻译工作和整理工作

(http://blog.sina.com.cn/s/blog_5dc8d9a50100kwuy.html)。

然后第二个类Splitter.java是分词的主类:

package ICTCLAS.kevin.zhang;

 

import java.io.IOException;

import java.io.UnsupportedEncodingException;

 

public class Splitter {

   

    private ICTCLAS2010 ictclas = null;//创建上边第一个类的对象

    private boolean available ;

   

    public Splitter() throws IOException {

       this.ictclas = new ICTCLAS2010();

       this.available = init();

    }

    //初始化

    private boolean init() throws IOException {

       String argu = ".";

       if (ictclas.ICTCLAS_Init(argu.getBytes("GB2312")) == false) {

           System.out.println("Init Fail!");

           return false;

       } else

           return true;

    }

   

    public int importUserDict(String userDict) throws UnsupportedEncodingException {

       if (available) {

           int nCount = ictclas.ICTCLAS_ImportUserDict(userDict

                  .getBytes("GB2312"));

           return nCount;

       } else

           return 0;

    }

    //分词

    public String split(String str, int tag) throws IOException {

       if (available) {

           String string;

           byte[] bytes = ictclas.ICTCLAS_ParagraphProcess(str

                  .getBytes("GB2312"), tag);

           string = new String(bytes, 0, bytes.length, "GB2312");

           return string.trim();

          

       } else

           return null;

    }

    //退出

    public void exit() {

       ictclas.ICTCLAS_Exit();

    }

   

}

我们在写一个测试的类Main.java:

package ICTCLAS.kevin.zhang;

//分词器调用测试类

import java.io.IOException;

 

public class Main {

 

    public static void main(String args[]) throws IOException{

       String s = "武汉大学校长顾海良" +

              "说武大梅园的风景很美,其实我就住在梅园!";

       //ICTCLAS2010 ictclas = new ICTCLAS2010();

       Splitter splitter = new Splitter();

       int n = splitter.importUserDict("userDic.txt");

       System.out.println("用户词典数量:"+n);

       String ss = splitter.split(s, 1).trim();

       System.out.println("分词结果:"+ss);

       String[] array = ss.split("\\s");

       for(String en : array){

           System.out.println(en);

       }

    }

}

程序的运行结果:

用户词典数量:4

分词结果:武汉大学/nt 校长/n 顾海良/nr 说/v 武大/n 梅园/ns 的/ude1 风景/n 很/d 美/a ,/wd 其实/d 我/rr 就/d 住/vi 在/p 梅园/ns !/wt

武汉大学/nt

校长/n

顾海良/nr

说/v

武大/n

梅园/ns

的/ude1

风景/n

很/d

美/a

,/wd

其实/d

我/rr

就/d

住/vi

在/p

梅园/ns

!/wt

 

我的用户词典userDic.txt的内容如下:

    武汉大学 nt

    顾海良 nr

    李白 nr

    梅园 ns

用户词典的前边词和右边的词性标注用空格分开

大家可以试着把用户自定义词典中的一些词去掉之后,看看分词的结构会有什么不同!

每个词后边的词性标注的符号含义,在刚才下载的文档中的“文档“文件夹下的ICTPOS3.0.doc文件中有详细介绍。如:nt是机构名,nr是人名,ns是地名

本程序的配置文件的内容如下:

<?xmlversion="1.0"encoding="GB2312"?>

<ICTCLAS>

    <DataPath>Data</DataPath>       //Data文件夹路径

    <TagSet>ICTPOS.map</TagSet>     //词性标注集映射文件

    <UserDict>on</UserDict>         //OnUserDictionaryapplied;Off:notapplied;

    <UserDictPrior>On</UserDictPrior>

 //用户词典优先,Addedin2006-03-16,requiredbyNECOn:用户词典和核心词典中同时有的词汇,用户词典优

 //先,本功能不要滥用,如果将核心词典中的词都设置为用户词典,其效果适得其反

    <FieldDict>off</FieldDict>      //On:FieldDictionaryapplied;Off:notapplied; 

    <GranularityContorl>off</GranularityContorl>

    <Log>On</Log>        //On,Off;例如:Off:关闭日志功能;On:打开日志功能

    <version>2010</version>         //系统版本号

    <Modify>2010-1-25</Modify>      //系统最近修订时间

    <Lexicon>2009-11-27</Lexicon>   //词典最近修订时间

    <Contact>pipy_zhang@msn.com</Contact>     //词典最近修订时间

</ICTCLAS>

 ICTCLAS2010的JNI调用实现过程以上程序是参考我的一个学长写的代码!使我受益匪浅,非常感谢他!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值