- 论坛徽章:
- 0
|
原帖地址:http://www.herofit.cn/2007/07/27_247
gedit 是 GNOME 桌面的小型文本编辑器。早些的gedit 不能自动检测文件编码,如果打开文件时不指定正确的编码就会出现“打开错误”的提示。我不知道gedit是从哪一个版本开始支持编码检测的,至少我现在用的gedit 2.18.1是支持的。
它是如何实现文件编码的自动检测的呢?我很好奇,于是开始读它的源码。经过两个多小时的指来指去 ,终于弄清楚它的实现机制。
编码检测的核心是 gedit/gedit-convert.c 里的 gedit_convert_to_utf8 和 gedit_convert_to_utf8_from_charset 函数。gedit_convert_to_utf8_from_charset 是glib中g_convert函数的封装。gedit_convert_to_utf8 的定义如下:
gchar *
gedit_convert_to_utf8 (const gchar *content,
gsize len,
const GeditEncoding **encoding,
gsize *new_len,
GError **error)
content是某未知编码的字符串,输入参数;
gsize是content的长度,输入参数;
encoding编码信息,可以为NULL,输入参数;
new_len是编码后的新长度,输出参数;
error指示错误,可以为NULL,输出参数。
该函数的处理流程如下:
如果指定了有效encoding,则直接调用gedit_convert_to_utf8_from_charset转换;
否则,通过 gedit/gedit-prefs-manager.c 中的 gedit_prefs_manager_get_auto_detected_encodings 函数得到一个候选的编码列表,然后开始循环,逐一调用 gedit_convert_to_utf8_from_charset 函数尝试将content转换成utf-8转换,如果转换无误(即转换后的字符经glib的 g_utf8_validate 函数检测无误),则认为当前测试的编码就是content的编码。
由于GB18030测试顺序在GBK和GB2312之前,且兼容后两者,所以GBK和GB2312这两个编码是不会出现在自动检测的结果里的。
gedit采用的方法不很聪明,但效果不错。如果不需要依赖glib就好了。
其实,我在网上搜索到一些专门猜 文件编码的项目,只依赖C标准函数库。 相信比较有用,但我现在上不了那些网站,只好有机会再去看了。
另外,unix的file命令也可以猜编码,有精力再看吧。
额外发现,gedit的所有“记忆”都保存在 ~/.gnome2/gedit-metadata.xml 文件里。 |
|