CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
【经验总结】不能实施并行处理的情况 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  ASP.NET

网站怎样支持简体和繁体中文版?

楼主lhlahh(lena)2005-06-27 11:30:44 在 .NET技术 / ASP.NET 提问

开发的网站怎样支持两种版本? 问题点数:0、回复次数:17Top

1 楼wf5360308(冷月孤峰)回复于 2005-06-27 11:37:52 得分 0

让你的软件支持繁体中文  
   
  中国台湾、香港的汉字用的是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”;  
   
                ……  
   
  }Top

2 楼wf5360308(冷月孤峰)回复于 2005-06-27 11:38:11 得分 0

简体转为繁体类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));  
   
                }  
   
                ……  
   
  }Top

3 楼wf5360308(冷月孤峰)回复于 2005-06-27 11:38:27 得分 0

这样写,是建立在待转换的流全部都是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   +=   "&nbsp;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;  
   
                                                          }Top

4 楼wf5360308(冷月孤峰)回复于 2005-06-27 11:38:58 得分 0

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编码浏览运行我们的软件,效果令人非常满意,几乎看不到什么乱码,已经达到了实用的效果。不过繁简切换是一个相当复杂的问题,并不是仅仅是简单地将简体字转换成繁体字就行了,有时还涉及到语义的问题。比如,简体中文中,不论“发展”的“发”还是“头发”的“发”都是同一个字,而在繁体中,它们是不同的两个字。这部分已经超出了笔者现有的水平,不在考虑之列了。Top

5 楼hackate(兰花开香入梦境,独思佳人亦飘然!!)回复于 2005-06-27 11:44:03 得分 0

用一个小软件,可以批量更改GB为BIG5,也可以BIG5转GB,非常方便  
  如果要,短信我Top

6 楼lhlahh(lena)回复于 2005-06-27 13:08:33 得分 0

谢谢   wf5360308(峰)   ,我先看看。Top

7 楼chx_xuxu(逍遥客)回复于 2005-06-27 13:24:04 得分 0

顶Top

8 楼ntcw(大卫)回复于 2005-06-27 13:30:05 得分 0

不需要哪么麻烦的,   不需要写一行程序,   即可以实现简繁的自动切换,   外挂一个DLL,   原站点几呼不用动.Top

9 楼wurekey(阿达)回复于 2005-06-27 13:35:03 得分 0

关注一下!Top

10 楼lhlahh(lena)回复于 2005-06-27 14:03:24 得分 0

to   ntcw(大卫)    
  能不能讲明白点Top

11 楼eqh(我想早恋,可已经晚了...)回复于 2005-06-27 14:10:43 得分 0

顶一下!Top

12 楼lywf(痛快去爱)回复于 2005-06-27 14:28:06 得分 0

MarkTop

13 楼dapanda()回复于 2005-06-27 14:45:32 得分 0

关注Top

14 楼smile9961(good life)回复于 2005-06-27 15:59:39 得分 0

关注Top

15 楼sykpboy(小憩---每天解决1个问题,顺便升星)回复于 2005-06-27 16:20:22 得分 0

考虑到文化差异,比如软件   和   软体,做简繁体网站最好不要用filter类的过滤器[包括isapi过滤组件],如果使用asp.net开发,建议采用资源文件实现多语言性.需要例子的话请留下email,我发给你.Top

16 楼lih163(做自己喜欢的事)回复于 2005-06-27 16:47:12 得分 0

繁简转换容易,但处理页面编码不好办Top

17 楼renyu732(Sysinfo)回复于 2005-06-27 16:58:27 得分 0

gzTop

相关问题

  • 《essential c++》的中文版(侯捷)是简体还是繁体的?
  • 在简体中文版Win9x下,怎样能直接输入繁体汉字?
  • DELPHI6简体中文版
  • 请问如何将现有简体中文网站,变成繁体中文版和英文版?
  • MysticBoy引进PureBasic3.92(简体中文版)可以制作不带任何库支持的EXE,控制台,DLL!
  • Install Shield V6.5 简体中文版下载?
  • Down: Office XP 简体中文版!
  • C++ Primer简体中文版的译序
  • Asp.Net快速上手简体中文版
  • 我看到Delphi6简体中文版了!

关键词

  • asp.net
  • b2b
  • 编码
  • 汉字
  • 简体
  • 转换
  • 代码
  • 软件
  • 中文
  • 页面

得分解答快速导航

  • 帖主:lhlahh

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
CSDN网站24小时值班电话:13552009689
Copyright © 2000-2009, CSDN.NET, All Rights Reserved
GongshangLogo