最近老大说要把我们的系统翻译成越南话和阿拉伯话.
当然, 不是让我们来做翻译, 是让我们把要翻译的东西导出来, 交给越南翻译和阿拉伯翻译. 但是老大说, 在给他们翻译的文件里, 最好有个”建议翻译”, 这样可以减少别人的工作量.
OK, 那么我们现在来看一下据说是目前全球最好的机器翻译系统——Google翻译.
首先, 这是一个设计给人用的界面(废话). 咳咳, 恩, 我的意思是说, 目前Google还没有一个可以直接通过程序访问的翻译API(又貌似是有一个, 但是附加条款很多, 且每天只能访问1000次, 等于对我们没用). 于是乎找到了这个项目.
很简单的一个东东, 用java写的, 核心部分就是用一个HttpURLConnection把Google翻译的网页搞下来, 然后分析字符串, 抠出翻译过的文字.
它里面附带了一个测试用的主类. 在里面用几个String把各种语言的”Hello world”保存在里面, 并调用Google的翻译, 将翻译结果与之对比. 我直接跑了一下, 居然……编译通不过? 提示”编码 GBK 的不可映射字符”.
去网上搜了一下, 终于知道原来netBeans(中文版)的默认编码字符集是”GBK”!
把netBeans的默认文件编码改成”UTF-8″, 并且修改了项目的编译属性之后, 总算可以运行了, 但是对比的结果大多都是错的.
于是又是一顿狂查资料, 前后差不多历时将近一个星期. 结论就是: java虚拟机有一个系统属性叫做默认字符集的东东(Charset.defaultCharset()), 在生成String对象的时候, 如果没有特别指定, 则使用默认字符集. 而这个默认字符集又是根据底层操作系统来决定的. 于是乎, 在Win XP下就成了”GBK”(此”GBK”非netBeans储存源代码时的默认编码”GBK”). 而那个获取Google网页的代码又是直接用BufferedReader.readLine()来读取的, 没有加任何字符集参数, 于是乎, 全都给编成GBK了. 导致的结果就是, 除了几个欧洲语言和中文之外, 其他如日语阿拉伯语朝鲜语俄语统统出错.
再次充分研读了Java API Doc之后, 重写了那个InputStream转到String的方法:
[coolcode lang="java" linenum="off"]
private static String toUTF8String(InputStream inputStream) throws IOException
{
Charset utf8 = Charset.forName(”UTF-8″);
CharsetDecoder utf8Dec = utf8.newDecoder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, utf8Dec));
StringBuilder sb = new StringBuilder();
String buffer;
while(null != (buffer = reader.readLine()))
{
sb.append(buffer);
sb.append(’\n’);
}
return sb.toString();
}
[/coolcode]
其中的重点在于:
1. 通过一个Charset对象生成一个对应该字符集的CharsetDecoder
2. 用这个CharsetDecoder生成InputStreamReader, 它将会使用指定的字符集编码规则, 将流中的数据转换成字符.
经过改造之后, 所有语言终于都返回了true. 但是还是有点不爽的就是, 阿拉伯语和朝鲜语在netBeans的输出里都变成了问号. 我后来又试了一下, 在cmd里面是同样的效果. 本来我怀疑是中文版的Windows不支持这两种语言, 但是我试着用阿拉伯语做名字新建了一个文件夹发现没有问题. 于是乎这个问题目前还暂时无解. 但是输出里看不到好像并不影响使用, 因为我尝试输出到文件里面, 再打开发现是正常的.
冲破层层艰难险阻, 终于可以从Google那里得到传说中的阿拉伯话了. 这时候组长大人突然告诉我说:”你不知道在短时间内访问Google太多次他就会让你输验证码么? 那个防病毒的机制…”
“哦”.
后来, 我们还是只给了他们纯英文的文件.