让你的软件支持繁体中文
中国台湾、香港的汉字用的是BIG5编码,而大陆的汉字用的是GB编码(GB2312也好,GBK也好),简体中文软件直接拿到繁体中文环境下运行,问题就出来了。
怎么办呢?
我们的软件是一款用C#.NET+ASP.NET开发的,所谓B/S型的软件,客户端只须用浏览器访问我们的服务器就行了。很自然的就想到,把代码中的所有的简体字都转换成繁体字,问题不就解决了吗?
说干就干。从网上找来了一款转换工具将全部代码文件转换了一遍。编译后运行,发觉静态的文字或提示信息确实已经变成了繁体,但从数据库中拿出来的还是简体(乱码),转换后的各种配置文件也读取出错(因为程序仍然按GB编码的格式进行读取)。还有一个问题,就是源代码只能转换一次。因为第一次转换后GB变成了BIG5,如果再转,就是BIG5转BIG5,结果变得不可辨认。由于源文件非常多,修改维护起来非常麻烦。
看来这种方法不可行。
那么能不能给我们的软件加上自适应的功能,增加对繁体中文的支持呢?
ASP.NET中,页面Page有个对象Response,该对象将 HTTP 响应数据发送到客户端,而Response有个获取或设置包装筛选器对象的属性Filter,用于在传输之前修改 HTTP 实体主体。当创建 Stream 对象并将 Response.Filter 属性设置为 Stream 对象时,所有由 Response.Write 发送的 HTTP 输出将通过筛选器。只要我们重载Stream类,在Stream类的Write()方法中将GB码转换成BIG5码,然后将Response.Filter = 重载Stream类,就可以达到在信息输出到客户端前先转换的效果。
//页面装载事件
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
Response.Filter = new CG2BFilter(Response.Filter);//设置筛选器
Response.Charset = “big5”;
……
}
简体转为繁体类CG2BFilter
public class CG2BFilter : Stream
{
……
//重载函数Write
public override void Write(byte[] buffer, int offset, int count)
{
WriteGB2BIG(buffer, offset, count);
}
//简体转为繁体
private void WriteGB2BIG(byte[] buffer, int offset, int count)
{
if( count == 0 )
{
return;
}
//936是简体中文代码页编号
Encoding e = Encoding.GetEncoding(936);
string str = e.GetString(buffer,offset,count);
//有些简体字没有对应的Big5,所以需要先转换成繁体的GB,再进行转换 for( int i=0;i<str.Length;i++ )
{
//_SGB是部分GB2312简体中文字库,_tGB则是对应的GB2312繁体字库
int j = _sGB.IndexOf(str[i]);
if( j != -1 )
{
str = str.Replace(_sGB[j],_tGB[j]);
}
}
//950是BIG5码代码页编号
e = Encoding.GetEncoding(950);
_sink.Write(e.GetBytes(str),0,e.GetByteCount(str));
}
……
}
这样写,是建立在待转换的流全部都是GB编码的基础上的,而大多数情况下也没有什么问题,不过,如果一个页面存在表单控件且控件内有汉字内容随同输出时,那么该页面在运行过程中有回传等刷新动作的话,就可能出现乱码。究其原因,是因为在页面第一次打开时,控件值由简体转成了繁体,回传的时候,则传回服务器的这部分控件值也为繁体。接着再输出,问题就来了:控件值为繁体,而页面本身还是简体,也就是说,输出流中存在混合编码,这样还一刀切将它们认为全是GB编码来加以转换就不行了,要加以区别。
怎么区别呢?BIG5与GB有什么区别吗?很遗憾,并没有什么明显的区别,也就是说,给你一个汉字编码,很难判断它究竟是GB还是BIG5。一般倾向于认为低字节在0x40~0x7F范围的就是BIG5码,因为没有简体字的低字节在这个范围。不过要注意,GB编码也有繁体字,并且这些繁体字的低字节也有位于0x40~0x7F的。所以这招并非万灵丹。
将数值从高字节0x81~0xFF,低字节0x40~0xFF这样组合输出到页面,如下:
string str = "";
Encoding gbe = Encoding.GetEncoding(936);
byte[] buffer = {0,0};
for( byte y = 0x81;y<0xFF;y++ )
{//高字节
str += "<br>";
for( byte x = 0x40;x<0xFF;x++ )
{//低字节
buffer[0] = y;
buffer[1] = x;
//以红色输出汉字,并注明其高低字节值
str += " 0x" + y.ToString("X") + x.ToString("X") + "<font color=\"red\" size=4>" + gbe.GetString(buffer) + "</font>";
}
}
Response.Write(str);
然后在浏览器里分别用GB编码和BIG5编码观察,你会发现,这两种编码中,都存在着有些字节值并没有相应的汉字,而是一些奇怪的符号、问号甚至是空白。于是可以这样认为:如果一个汉字的字节值在某种编码中找不到汉字,则说明它不属于这种编码。经过认真比较归纳,两种编码都划定了一些范围,然后可以逐个考察输出流中的汉字,看它是否落在该范围,以此判定它属于何种编码。
虽然划定了一些范围,但GB和BIG5重叠的区域实在太多,有许多字用两种编码去套,好象都可以,逐个字转换,误差很大。后来发现了一个很重要的思想,就是:在混合汉字编码的流中,不同的汉字编码总是不相邻的,它们中间有西文字符隔开(因为网页中,控件值都包含在许多HTML标记之间),也就是说,如果有一个汉字确定是某种编码,则可以推断与它相邻的所有汉字都属于同一种编码。事实证明,这种思想使得转换的准确性得到大幅度的提高。
修正后的类CG2Bfilter:
public class CG2BFilter : Stream
{
……
public override void Write(byte[] buffer, int offset, int count)
{
int p = offset;
int q = p;
int limit = offset + count;
//这里定义了两个看似互相矛盾的布尔量:maybeBig,notBig,主要是让它们配合使用。maybeBig表明一段流中出现了有Big5编码特征的汉字,因此可能是大五码但不能肯定,而notBig表明一段流出现了不可能是Big5编码的汉字,则这段流肯定不是大五码。一段流只有在maybeBig为真,且notBig为假时才可能认为它是大五码。
bool maybeBig = false;
bool notBig = false;
bool isChinese = false;
while( p < limit )
{
if( buffer[p] >= 0x81 && buffer[p] <= 0xFE )
{//汉字
if( !isChinese )
{//此前不是汉字,先输出
WriteAscii(buffer,q,p-1-q+1);// 待处理的流是西文字符 isChinese = true;
q = p;
}
p++;
if( p >= limit )
{
break;
}
if( buffer[p] >= 0x40 && buffer[p] <= 0x7E
|| buffer[p-1] >= 0xA1 && buffer[p-1] <= 0xA3 && buffer[p] >= 0x40 && buffer[p] <= 0xA0
|| buffer[p-1] >= 0xA4 && buffer[p-1] <= 0xA9
|| ( buffer[p-1] >= 0xAA && buffer[p-1] <= 0xAF || buffer[p-1] >= 0xF8 && buffer[p-1] <= 0xFD ) && buffer[p] >= 0xA1 && buffer[p] <= 0xFE )
{//很可能是BIG5,由此可以推断,这相邻的汉字串都可能是BIG5
maybeBig = true;
}
if( buffer[p] >= 0x7F && buffer[p] <= 0xA0
|| buffer[p-1] >= 0x81 && buffer[p-1] <= 0xA0
|| buffer[p-1] == 0xC6 && buffer[p] >= 0x7F && buffer[p] <= 0x0FE
|| buffer[p-1] >= 0xC7 && buffer[p-1] <= 0xC8
|| buffer[p-1] == 0xF9 && buffer[p] >= 0xDC
|| buffer[p-1] >= 0xFA )
{//肯定不是BIG,因为在此区间,BIG为空
notBig = true;
maybeBig = false;
}
}
else
{//非汉字
if( isChinese )
{//此前是汉字,先输出
if( maybeBig && !notBig)
{
WriteBIG(buffer,q,p-1-q+1);//待处理的流是BIG5
}
else
{//不肯定是繁体
WriteGB2BIG(buffer,q,p-1-q+1);// 待处理的流是GB
}
isChinese = false;
maybeBig = false;
notBig = false;
q = p;
}
}
p++;
}
//将while语句最后一轮循环未处理的部分在这里处理
if( isChinese )
{
if( maybeBig && !notBig )
{
WriteBIG(buffer,q,p-1-q+1);
}
else
{
WriteGB2BIG(buffer,q,p-1-q+1);
}
}
else
{
WriteAscii(buffer,q,p-1-q+1);
}
}
//处理对象为GB
private void WriteGB2BIG(byte[] buffer, int offset, int count){……}
//处理对象为BIG5
private void WriteBIG(byte[] buffer, int offset, int count){……}
//处理对象为ASCII
private void WriteAscii(byte[] buffer, int offset, int count){……}
……
}
应用修正过的类后,浏览器用BIG5编码浏览运行我们的软件,效果令人非常满意,几乎看不到什么乱码,已经达到了实用的效果。不过繁简切换是一个相当复杂的问题,并不是仅仅是简单地将简体字转换成繁体字就行了,有时还涉及到语义的问题。比如,简体中文中,不论“发展”的“发”还是“头发”的“发”都是同一个字,而在繁体中,它们是不同的两个字。这部分已经超出了笔者现有的水平,不在考虑之列了。
分享到:
相关推荐
最著名的网络终端软件之一,现在它完全支持简体和繁体版Windows95/NT,而且支持在英文版Windows上使用的第三方产品如RichWin和Unionway。此版本含中文多种语种可供选择。
能够让你随心所欲地将简体文件转换成繁体文件。转换速度相当快和具有「简转繁列表」提高辨识率来更正GB转 Big5后繁简异字的问题、支持同时转换多个文件文件、提供文件及剪贴簿内码转换,且无文件大小限制等。另外,...
Sublime Text的简体中文和繁体中文翻译。3.支持MainMenu TabMenu ContextMenu等。
繁体字输入法是一款兼容所有中文输入法的繁体字即时转换软件,不管您用拼音还是五笔输入法,打出来的字都自动转换成繁体字。除此之外,还能随意打出像*^_^*、(⊙o⊙)、(^_^)/~~这样的个性符号,方便极了!当中还有更...
WinRAR 64位 繁体中文版,支持去除广告,官网的软件没有f墙下载很慢,所以发布在这方便大家下载。广告去除方法就是添加“rarreg.key”文件,具体网上搜 很多教程。
串口&网络摄像头软件XCAM V1.0功能简介: 1,支持串口接收JPEG数据流并显示,串口波特率可自定义 2,支持网络接收JPEG数据流并显示,支持TCP ...6,支持简体中文、繁体中文和英文三种语言 7,支持正点原子软件仓库
Sublime Text 2.0.2 ST...下载安后解压到/usr/lib/sublime-text-2/中即可使用,繁体中文汉化菜单, 免注册,无乱码,默认支持GBK,GB2312 软件截图见:http://sublimetext.iaixue.com/forum.php?mod=viewthread&tid=8
繁体中文汉化菜单,无中文乱码,默认支持GB2312/GBK/BIG5等. 软件截图见:http://sublimetext.iaixue.com/forum.php?mod=viewthread&tid=35。 使用说明: 请解压到/opt/目录下,首次使用请以当前用户身份先运行...
下载解压后即可用,繁体中文汉化菜单,免注册,无中文乱码,默认支持GB2312/GBK/BIG5等。 软件截图见:http://sublimetext.iaixue.com/forum.php?mod=viewthread&tid=34。 附: Sublime Text 3中为什么要选择使用...
繁体中文的简述:繁体中文(Traditional Chinese),是中华民族传统文化中所使用的标准中文字体,目前已有二千年以上的历史。 繁体中文的使用地区:在20世纪之前一直是全球各地华人中通用的中文书写标准。目前,...
软件介绍: 本汉字查询工具字库:常用汉字6905个。 繁体字及繁体笔画因编码和计算方法不统一 繁体字及繁体笔画输出的结果仅供参考 五笔编码对应的汉字为简体文字 五笔编码查询支持“z”模糊查找 拼音查询...
EasyJForum 是一个基于 Java 技术的免费社区论坛软件系统,界面与目前流行的 Discuz! 系统相仿以方便用户使用,其基本目的是为基于 Java 平台的中文站点提供最好的论坛服务。通过本系统,网站架设者不需要进行任何...
在完全支持GB2312-80简体汉字字符集的基础上,选择增加一些GBK汉字,避免了传统五笔对于“镕”、“瞭(望)”、“啰(嗦)”、“堃”、“槃”、“旻”、“冇”等汉字不能输入的尴尬,其实用性能是相当不错的。...
大众FTP软件是一款界面友好功能强大并且简单易用的中文FTP软件,通过它你可以自由自在地存取和管理FTP服务器的资源。...■ 支持中文界面,支持中文FTP服务器响应,可选择简体或繁体中文。 大众FTP软件截图
aSc Timetables可以帮助你轻松、快速的创建出包含大量班级与教师的完整课程...语言选择:这款软件虽然说是支持简体中文、繁体中文,但西西测试发现,简体中文显示完全是乱码,繁体中文只有选择HongKong显示才比较正常。
BullZip PDF Printer(虚拟打印机)是一款虚拟打印机驱动程序,让你可以转换任何可打印...PDF Creator软件全面支持简体中文、繁体中文和unicode。
多国语言支持,包括简体、繁体中文(Linux平台需额外安装“filezilla-locales”套件); 可通过Kerberos进行GSS验证与加密。 FileZilla是一个免费开源的FTP解决方案,分为客户端版本和服务器版本,具备所有的FTP...
文本文件中必须全部是全角字符,包括字母和数字,而且程序会自动剔除一些一般五笔输入法无法录入的汉字,如繁体字等),考试时您无需记录,系统会将考号、姓名、考试时间、所用的考试文本、正确字数、错误字数、正确...
有些精简的WIN7系统,没有繁体语言包,系统无法输入繁体字,也不支持繁体界面的软件,如香港和台湾开发的一些繁体应用程式。
商速英文版商超进销存软件支持语言:简体中文,繁体中文,英语,法语,俄语,西班牙语,日语,葡萄牙,韩语,阿拉伯等语言。 商速英文版商超进销存软件功能介绍 1.软件安装操作简单,有中文与英语的安装视频讲解 ...