微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverlight读取包含中文的txt(解决乱码问题)

虽然Silverlight已经是被抛弃的孩子了,但此前做的一些项目还是用到Silverlight。今天用Silverlight导入客户端本地的一个txt文件,然后读取需要的信息。随手记录一下,留作以后备忘。

网上也有不少的相关资料,但好像要么是单纯的Ctrl+C、Ctrl+V,要么是不够齐全。闲话少说,直接上代码

我用的是MVVM模式,所以用RelayCommand命令打开了。其它的,直接在类似Button_Click事件里调用OpenFile(),同理。


 
        /// <summary>
         /// 打开文件
         /// </summary>
         private void OpenFile()
         {
             try
             {
                 //检查是否是在OOB模式下运行
                 OOBChecker.CheckInstallState(() =>
                 {
                     //弹出选择文件对话框
                     OpenFileDialog fileDialog = new OpenFileDialog()
                     {
                         Filter = "Txt Files (*.txt)|*.txt|All Files (*.*)|*.*",};
 
                     if (fileDialog.ShowDialog() == true)
                     {
                         //读取文件流
                         using (Stream fs = fileDialog.File.OpenRead())
                         {
                             ReadTxtFile(fs);
                             fs.Close();
                         }
                     }
                 });
             }
             catch (Exception e)
             {
 
                 //错误处理
             }
         }

注: OOBChecker.CheckInstallState,是为公司项目需要写的一个检查Silverlight程序是否在浏览器外运行的方法。众所周知,Silverlight是可以安装在本机脱离浏览器运行的,这样便可获得更高的执行权限。有时对本地文件(夹)进行操作时,程序需要获得信任权限。不知是否我浏览器设置问题,我直接在IE上运行,貌似也有权限。

附上OOBChecker的代码

   public class OOBChecker
        {
            /// <summary>
            /// 当前程序是否安装在本地
            /// </summary>
            private static bool IsInstall { get; set; }

            /// <summary>
            /// 检查当前程序有没有安装在本地,callback是回调
            /// </summary>
            public static void CheckInstallState(Action callback)
            {
                try
                {
                    if (App.Current.HasElevatedPermissions)
                    {
                        //跳过OOB验证,直接在网页打开
                        if (callback != null)
                        {
                            callback();
                            return;
                        }
                    }

                    if (App.Current.InstallState == InstallState.Installed)
                    {
                        if (App.Current.IsRunningOutOfbrowser)
                        {
                            IsInstall = true;

                            //项目中操作Office COM需要
                            if (AutomationFactory.IsAvailable)
                            {
                                if (callback != null)
                                {
                                    callback();
                                }
                            }
                            else
                            {
                                MessageWindow.CreateNew("您好,AutomationFactory IsAvailable Is False",resTip@R_193_404[email protected]);
                            }

                            //App.Current.MainWindow.TopMost = true;
                        }
                        else
                        {
                            MessageWindow.CreateNew("您好,您已在本机安装了模块程序,请保存本页面数据后双击运行桌面的图标。",resTip@R_193_404[email protected]);
                        }
                    }
                    else
                    {
                        MessageWindow.CreateNewConfirm("打开文档之前需要安装本程序在您电脑上,确定帮您安装吗?为避免数据丢失,请确认前先保存数据。",resTip@R_193_404[email protected],() =>
                            {
                                App.Current.InstallStateChanged += Current_InstallStateChanged;
                                App.Current.Install();
                            });
                    }
                }
                catch (Exception ex)
                {
                    ErrorWindow.CreateNew(ex);
                    Debug.WriteLine(string.Format("{0} at {1}",ex.Message,"OOBChecker"));
                }
            }

            /// <summary>
            /// 安装完成后
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private static void Current_InstallStateChanged(object sender,System.EventArgs e)
            {
                if (App.Current.InstallState == InstallState.Installed)
                {
                    IsInstall = true;
                }
            }
        }

View Code

 

OpenFile方法中,调用一个读取文件内容方法ReadTxtFile


         /// <summary>
         /// 一行行地循环读取
         /// </summary>
         private void ReadTxtFile(Stream fs)
         {
             var myTable = new List<string>();
             using (StreamReader reader = new StreamReader(fs,new Gb2312Encoding()))
             {
                 /*
                  * 一次性读出所有文件信息
                  * var fileText = string.Empty;
                 fileText = reader.ReadToEnd();
                  */
 
                 reader.BaseStream.Seek(0,SeekOrigin.Begin);
                 string strLine = reader.ReadLine();
                 var tableIndex = 0;
                 while (strLine != null)
                 {
                     /*
                      * do your things here
                     if (strLine.Contains("[Your message is here]"))
                     {
                         //找到表头了
                         tableIndex++;
                     }
 
                     if (tableIndex > 6)
                     {
                         //读完需要的表信息了,跳出
                         break;
                     }
 
                     if (tableIndex >= 4)
                     {
                         //开始获取需要的信息
                         myTable.Add(strLine);
                     }
                     if (tableIndex > 0)
                     {
                         tableIndex++;
                     }
                     */
                     strLine = reader.ReadLine();
                 }
                 reader.Close();
             }
 
             if (myTable.Any())
             {
                 foreach (var strItem in myTable)
                 {
                     var view = strItem.TrimEnd('\t').Split('\t');
                     //do something here
                 }
             }
 
         }


注:Silverlight不支持GB2312编码,所以打开中文时会乱码。为此,我们可以继承Encoding,自己为程序添加GB2312编码。然后像下面那样调用

StreamReader reader = new StreamReader(fs,new Gb2312Encoding()) 
Gb2312Encoding代码,里面包含了个Gb2312toUnicodeDictinary(这个是网上找的,很多网上资料只有Gb2312Encoding,却没有附上Gb2312toUnicodeDictinary)。
只上Gb2312Encoding代码吧,Gb2312toUnicodeDictinary有7000多行的说……,这两个文件以附件形式放在后面,有需要的童鞋自行下载。

  public class Gb2312Encoding : Encoding
     {
         public override string WebName
         {
             get
             {
                 return "gb2312";
             }
         }
 
         public Gb2312Encoding()
         {
 
         }
         public override int GetBytes(char[] chars,int charIndex,int charCount,byte[] bytes,int byteIndex)
         {
             throw new NotImplementedException();
         }
 
         public override int GetChars(byte[] bytes,int byteIndex,int byteCount,char[] chars,int charIndex)
         {
             int j = 0;
             char c;
             for (int i = 0; i < byteCount; i += 2)
             {
                 if (i + 1 >= bytes.Length)
                 {
                     char[] last = Encoding.UTF8.GetChars(new byte[] { bytes[i] });
                     chars[j] = last[0];
                 }
                 else
                 {
                     byte[] bb = new byte[] { bytes[i],bytes[i + 1] };
                     if (Gb2312toUnicodeDictinary.TryGetChar(bb,out c))
                     {
                         chars[j] = c;
                         j++;
                     }
                     else
                     {
                         char[] tt = Encoding.UTF8.GetChars(new byte[] { bb[1] });
                         chars[j] = tt[0];
                         j++;
                         //测试下一个
                         if (i + 2 >= bytes.Length)
                         {
                             char[] tttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
                             chars[j] = tttt[0];
                             j++;
                         }
                         else
                         {
                             byte[] test = new byte[] { bb[0],bytes[i + 2] };
                             if (Gb2312toUnicodeDictinary.TryGetChar(test,out c))
                             {
                                 chars[j] = c;
                                 j++;
                                 i++;
                             }
                             else
                             {
                                 char[] ttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
                                 chars[j] = ttt[0];
                                 j++;
                             }
 
                         }
                     }
                 }
             }
 
             return chars.Length;
         }
 
         public override int GetByteCount(char[] chars,int index,int count)
         {
             return count;
         }
         public override int GetCharCount(byte[] bytes,int count)
         {
             return count;
         }
 
         public override int GetMaxByteCount(int charCount)
         {
             return charCount;
         }
         public override int GetMaxCharCount(int byteCount)
         {
             return byteCount;
         }
         public static int CharacterCount
         {
             get { return 7426; }
         }
     }

View Code

 

 附件(GB2312Encoding+GB2312toUnicodeDictinary)下载




版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐