2007年11月 存档

مرحبا العالم

2007年11月26号,星期一

最近老大说要把我们的系统翻译成越南话和阿拉伯话.

当然, 不是让我们来做翻译, 是让我们把要翻译的东西导出来, 交给越南翻译和阿拉伯翻译. 但是老大说, 在给他们翻译的文件里, 最好有个”建议翻译”, 这样可以减少别人的工作量.

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太多次他就会让你输验证码么? 那个防病毒的机制…”

“哦”.

后来, 我们还是只给了他们纯英文的文件.

我来啦~

2007年11月11号,星期天