设为首页 收藏本站
查看: 1838|回复: 0

[经验分享] hadoop上利用JNI分词

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2015-7-15 09:19:20 | 显示全部楼层 |阅读模式
  虽然有streaming方式,但是碍于本人蹩脚的C++,还是决定由JNI方式来进行分词,下面是具体环境:
  hadoop:0.201


linux :2.6.16.60-0.21-TENCENT64-110923

jdk:Java(TM) SE Runtime Environment (build 1.6.0_17-b04),Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)



TCWordSeg所必需的文件:

DSC0000.gif



DSC0001.gif

其中libTCWordSeg.so是分词的库文件,而TCWordSeg.jar中包含了所有的类和方法原型。

还有一个词典文件夹 data,其中包含了分词工具所必需的所有词典文件:







为了能更好更方便的使用分词,写了一个包装的类,在写代码之前,将TCWordSeg.jar添加到buildpath中。WordSeg4J 代码如下:





View Code


1 import java.io.IOException;
2 import org.mortbay.log.Log;
3 import com.tencent.research.nlp.*;
4  
5 public class WordSeg4J {
6  
7 public static String dictDir = "data";
8 public static int SEG_MODE =1;
9 static{
10 System.loadLibrary("TCWordSeg");
11 SEG_MODE = TCWordSeg.TC_POS | TCWordSeg.TC_S2D
12 | TCWordSeg.TC_U2L | TCWordSeg.TC_T2S | TCWordSeg.TC_ENGU
13 | TCWordSeg.TC_CN | TCWordSeg.TC_USR;
14  
15 try {
16 TCWordSeg.TCInitSeg(to_cstr_bytes(dictDir));
17 } catch (IOException e) {
18 // TODO Auto-generated catch block
19 System.out.println(e.getMessage());
20 Log.info(e.getMessage());
21 }
22 }
23  
24 public static String segString(String str) {
25 SWIGTYPE_p_void seghandle = TCWordSeg.TCCreateSegHandle(SEG_MODE);
26 //System.out.println(str);
27 String line_seg = "";
28 /* 以 GBK 字节流的方式提供待切分句子 */
29 try {
30 TCWordSeg.TCSegment(seghandle, to_cstr_bytes(str));
31 int rescount = TCWordSeg.TCGetResultCnt(seghandle);
32 for (int i = 0; i < rescount; i++) {
33 byte[] word_bytes = TCWordSeg.TCGetWordAt(seghandle, i);
34 String word = new String(word_bytes, "GBK");
35 line_seg += word + " ";
36 }
37 } catch (IOException e) {
38 // TODO Auto-generated catch block
39 System.out.println(e.getMessage());
40 }
41  
42 return line_seg;
43 }
44  
45 /*
46  * 注意: 在 C 接口中传入参数类型为 char * 的地方, Java 接口中全部 使用参数类型 byte[], 并且 byte[] 数组必须以
47  * '\0' 结束。 这是为了解决GBK 编码字符串在 C  Java 中转换的问题
48  */
49 public static byte[] to_cstr_bytes(String str) throws IOException {
50 String s = str + '\0';
51 return s.getBytes("GBK");
52 }
53 }
  ps:如果您经常使用这个类,建议将其打包为jar,推荐使用eclipse的fatjar工具,将TCWordSeg.jar一起打包成一个jar,或者用ANT打包。


写完了包装类,就可以在Mapper或者Reducer中使用这个类的静态方法了。但是先别急着些驱动程序,还有两件事最好先完成:

1)分别将libTCWordSeg.so和data文件夹打包成lib.tar和data.tar,当然也可以打包成zip或者jar、gzippedtar等形式。

2)将上面两个tar文件上传到hdfs中,假设它们的hdfs路径分别为 /path/lib.tar 和/path/data.tar

好了,现在就可以写驱动程序了,在写驱动程序的时候,需要注意利用hadoop的一个重要特性:DistributedCache,关于这个东西的详细介绍,网络上一大堆,自己可以去看。

在驱动程序中,需要加入下面这么几行代码:



View Code


1 DistributedCache.createSymlink(conf);
2            
3 Path filePath = new Path(" /path/lib.tar");
4 String uriWithLink = filePath.toUri().toString(); DistributedCache.addCacheArchive(new URI(uriWithLink), conf);
5  
6 Path filePath2 = new Path("/path/data.tar");
7 String uriWithLink2 = filePath2.toUri().toString();
8 DistributedCache.addCacheArchive(new URI(uriWithLink2), conf);   
  好了,之后用fatjar将程序打包,将TCWord.jar也一起打入,之后就可以在hadoop上运行程序了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-86806-1-1.html 上篇帖子: 用C# 连接 hadoop,hive,hbase的一些代码 下篇帖子: Hadoop安装部署(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表