大道至简,知易行难
广阔天地,大有作为

在Java中进行中文繁体简体转换,基于OpenCC(Open Chinese Convert)方案

一、OpenCC介绍
      OpenCC (Open Chinese Convert,开放中文转换) 是一个用于中文简繁转换的开源项目,支持词汇级别的转换、异体字转换和地区习惯用词转换(中国大陆、台湾、香港),其官网位于Github中:https://github.com/BYVoid/OpenCC。
      OpenCC严格区分「一简对多繁」和「一简对多异」,完全兼容异体字,支持中国大陆、台湾、香港异体字和地区习惯用词转换,词库和函数库完全分离,支持C、C++、Python、PHP、Java、Ruby、Node.js和Android,兼容Windows、Linux、Mac平台。
      在Github的Wiki中,有对OpenCC的详细介绍和与cconv的对比,对于现代汉语常用简繁一对多字义、地名等也进行了支持,从介绍上看应该是一个较优秀的解决方案。
二、OpenCC二进制文件的获取
      在本站的《使用Visual Studio 2017(VS2017)编译OpenCC 1.0.4 (Open Chinese Convert)源代码》一文中,描述了如何在Windows平台下编译OpenCC 1.0.4。为便于读者使用,所编译出的文件(opencc.dll、opencc.lib)可从CSDN上直接下载;其他操作系统下的编译请参阅其他相关文档。
三、在Java中调用OpenCC进行中文繁体简体转换
3.1 如何从Java中调用DLL
      在本站的《在Java中调用DLL动态链接库,基于JNA方案》一文中,描述了如何使用JNA在Java中调用动态链接库的方案,在此不再赘述。在本文最后也给出完整的工程,JNA的使用方式非常简单,没有用过JNA的直接看代码也可以。
3.2 查看opencc.dll导出的API
      为了构造JNA的Stub代码,我们必须了解opencc.dll中导出接口的定义,可以通过三种方式进行:
①通过opencc.h头文件(推荐)
opencc.h头文件中定义了所有导出的函数,主要包括:
OPENCC_EXPORT opencc_t opencc_open(const char* configFileName);
OPENCC_EXPORT opencc_t opencc_open_w(const wchar_t* configFileName);
OPENCC_EXPORT int opencc_close(opencc_t opencc);
OPENCC_EXPORT size_t opencc_convert_utf8_to_buffer(opencc_t opencc, const char* input, size_t length, char* output);
OPENCC_EXPORT char* opencc_convert_utf8(opencc_t opencc, const char* input, size_t length);
OPENCC_EXPORT void opencc_convert_utf8_free(char* str);
OPENCC_EXPORT const char* opencc_error(void);
如下图所示:
通过opencc.h头文件查看opencc.dll的导出函数

通过opencc.h头文件查看opencc.dll的导出函数

②使用dumpbin工具
dumpbin工具是VisualStudio自带的工具,不能从CMD中而需要从开发人员命令提示符中运行,使用命令
dumpbin /EXPORTS opencc.dll
即可:
使用dumpbin命令获取dll动态链接库的导出API

使用dumpbin命令获取dll动态链接库的导出API

③使用Dependency Walker(即原VC6中的denpends.exe)
Dependency Walker早在VC6时代就已经存在,用于查看DLL动态链接库的依赖及导出函数等,但VS2017中已经没有这个工具了,据传其被删除的原因是该工具被Windows SDK组评估为质量不合格。我们可以从http://www.dependencywalker.com上下载Dependency Walker,并利用其分析opencc.dll的导出函数,如下图所示:
使用DependencyWalker查看oepncc.dll的导出函数

使用DependencyWalker查看oepncc.dll的导出函数

3.3 构造JNA的Stub代码
      根据JNA的类型映射规范,我们可以构造出如下的Stub类代码(同时请注意图中opencc.dll、配置文件及ocd文件的位置):
使用Java调用OpenCC时的JNA接口代码

使用Java调用OpenCC时的JNA接口代码

对应代码为:

package com.mei.opencc;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.WString;

public interface Opencc extends Library
{
 Opencc INSTANCE = (Opencc) Native.loadLibrary(“opencc”, Opencc.class);

 public Pointer opencc_open(String configFileName);

 public Pointer opencc_open_w(WString configFileName);

 public int opencc_close(Pointer opencc);

 public int opencc_convert_utf8_to_buffer(Pointer opencc, String input, int length, String output);

 public String opencc_convert_utf8(Pointer opencc, String input, int length);

 public void opencc_convert_utf8_free(String input);

 public String opencc_error();
}

3.4 编写Java调用opencc.dll的测试代码
以下为Java调用opencc.dll的测试代码。有关opencc的使用请参见相关的官方文档,以下为繁体中文转简体中文,使用默认的t2s配置文件,在此不再赘述:
使用Java调用OpenCC时的测试代码

使用Java调用OpenCC时的测试代码

对应的代码为:

package com.mei.opencc;

import com.mei.opencc.Opencc;
import com.sun.jna.Pointer;

public class OpenccTest
{
 public static void main(String[] args)
 {
  try
  {
   String configFileName = “E:\\workspace-sts-3.3.0.RELEASE\\OpenccJavaTest\\lib\\t2s.json”;
   Pointer opencc = Opencc.INSTANCE.opencc_open(configFileName);
   if (Pointer.nativeValue(opencc) == -1)
   {
    System.err.println(Opencc.INSTANCE.opencc_error());
    return;
   }

   String input = “中文簡繁轉換開源項目,支持詞彙級別的轉換、異體字轉換和地區習慣用詞轉換(中國大陸、臺灣、香港)”;
   String output = Opencc.INSTANCE.opencc_convert_utf8(opencc, input, Integer.MAX_VALUE – 1);
   if (output == null)
   {
    System.err.println(Opencc.INSTANCE.opencc_error());
    return;
   }
   System.out.println(output);

   Opencc.INSTANCE.opencc_convert_utf8_free(output);
   System.out.println(Opencc.INSTANCE.opencc_close(opencc));
  }
  catch (Exception e)
  {
   System.err.println(e.toString());
  }
 }
}

需要注意:
①opencc.dll应该使用32位版本还是64位版本是需要根据JDK或JRE是32位还是64位而决定的,如果使用了不正确的版本会报错“java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序”;
文件编码应设置为UTF-8,否则由于字符串的编码问题,在调用opencc_convert_utf8时会报错“Invalid UTF8”并返回null;
③调用opencc_open时配置文件的路径必须为绝对路径,如果路径中含有中文等需要使用opencc_open_w;
④如果opencc_open调用失败,返回的指针为-1,请注意判断,并使用opencc_error获取出错原因
⑤调用opencc_open时,可能需要用到*.ocd文件,该文件必须与配置文件放在同一路径下,否则会报错形如“TSPhrases.ocd not found or not accessible.”等;
⑥调用opencc_convert_utf8时,最后一个参数为length字段,文档中明确指出“If length is (size_t)-1, the whole string (terminated by ‘\0’) will be converted.”;
⑦需要调用opencc_convert_utf8_free释放转换后的结果
我们可以看到,上述繁体中文被成功转换成了中文:
 
使用Java调用OpenCC时的测试代码输出

使用Java调用OpenCC时的测试代码输出

3.5 Java调用opencc.dll的完整工程(x64)
Java调用opencc.dll的完整工程(x64)位于GitHub中,请戳此查看,如果有用欢迎Star。

转载时请保留出处,违法转载追究到底:进城务工人员小梅 » 在Java中进行中文繁体简体转换,基于OpenCC(Open Chinese Convert)方案

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址