谨慎使用Encoding.Default

     在处理文本时,经常需要处理Encoding的概念。存在这个问题的原因在于,在.NET程序内文本只是string和char对象,而保存到硬盘时,或者准备用socket把它发送出去时,都得先转换成byte[]或者字节流。而转换的算法,就是Encoding。Encoding不同文本文件的行数也不同。

老外的程序里面,都喜欢用Encoding.ASCII,这是因为他们主要只使用western字符;于是我们经常要在他们的代码把Encoding.ASCII替换成Encoding.Default才能使用。

所谓Encoding.Default,是指当前系统设置的“默认字符集编码方式”。你可以通过控制面板里面的区域选项设置它(这是在我的机器上的设定):



 

 

注意红色方框内的部分,“为你的非Unicode程序选择一个语言来匹配其本地语言版本”。这里选择了Chinese (PRC),则Encoding.Default等效于Encoding.GetEncoding("gb2312")。gb2312在代码页936,所以所有以双字节编码(ANSI编码)字符的程序在这个系统上会使用936代码页,使用Unicode的不受影响。

你可以看到 Encoding.Default的值是和系统设定相关的。这样,有些时候会出问题:一台机器用socket发送一段文本到另一台机器,两边都设定编码方式为Encoding.Default,但两台机器的区域选项的这个设置是不一样的,却没有被注意;如果发送的是非western字符,则接受方必然会得到乱码。这种问题往往会令人很困惑。

所以在面对中文且为ANSI编码的情况下,最好不要用Encoding.Default,而用 Encoding.GetEncoding("gb2312"),或者更直接的Encoding.GetEncoding(936);而如果有可能的话,最好全部使用unicode,比如utf-8,也就是Encoding.UTF8。有了unicode之后,其实我们不需要代码页的概念。

 

private void ConnectPlatform() //打开控制卡与配置 { int netid, imcid, i; string err; netid = NetworkCard.SelectedIndex; imcid = ControlCardID.SelectedIndex; if (Global.isOpen())//设备已打开则关闭 { IMC_Pkg.PKG_IMC_Close(Global.g_handle); Global.g_handle = IntPtr.Zero; OpenControlCard.Text = "打开控制卡"; timer1.Enabled = false; } else { //有3种方法可连接控制卡,根据需要选择其中一个方法 #if true //方法1, Global.g_handle = IMC_Pkg.PKG_IMC_Open(netid, imcid); #elif false //方法2,使用方法1无法打开通过无线网卡连接的控制卡时,可使用方法2打开 Global.g_handle = IMC_Pkg.PKG_IMC_OpenX(netid, imcid, 40, 1); #else //方法3,使用密码连接控制卡 byte[] password = new byte[32]; string pw = "123456"; //此密码由iMCAT-6xxE软件或者PKG_IMC_SetPassword函数得到 password = System.Text.Encoding.Default.GetBytes(pw); Global.g_handle = IMC_Pkg.PKG_IMC_OpenUsePassword(netid, imcid, ref password[0], 6); #endif if (Global.isOpen()) { OpenControlCard.Text = ("关闭控制卡"); timer1.Enabled = true; //启动定时器,定时读取位置信息 Global.GetIMCInfo(); if (Global.g_naxis > 0) { ListViewItem lvitem; AxisMonitor.Items.Clear(); for (i = 0; i < Global.g_naxis; i++) { lvitem = AxisMonitor.Items.Add("轴" + i.ToString()); lvitem.SubItems.Add(("0")); lvitem.SubItems.Add(("0")); lvitem.SubItems.Add(("0x0000")); m_error_t[i] = 0; //存储第 i 个轴的错误状态或代码 m_curpos_t[i] = 0; //存储第 i 个轴的指令位置 m_encp_t[i] = 0; //存储第 i 个轴的编码器位置 } lvitem = AxisMonitor.Items.Add("encs"); lvitem.SubItems.Add(("0")); lvitem.SubItems.Add(("Ecat Error:")); lvitem.SubItems.Add(("0x00000000")); m_encs_t = 0; m_EcatErr_t = 0; } else { err = Global.GetFunErrStr(); MessageBox.Show(err); } } else { MessageBox.Show(("无法打开控制卡!\r\n\r\n请检查网卡和控制卡ID是否选择正确!")); } } } 我这个代码是在线程A中使用的,而NetworkCard、ControlCardID、timer1、AxisMonitor等控件是在UI线程的,我要如何修改代码
03-13
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值