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


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

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

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

     1         /// <summary>
     2         /// 打开文件
     3         /// </summary>
     4         private void OpenFile()
     5         {
     6             try
     7             {
     8                 //检查是否是在OOB模式下运行
     9                 OOBChecker.CheckInstallState(() =>
    10                 {
    11                     //弹出选择文件对话框
    12                     OpenFileDialog fileDialog = new OpenFileDialog()
    13                     {
    14                         Filter = "Txt Files (*.txt)|*.txt|All Files (*.*)|*.*",
    15                     };
    16 
    17                     if (fileDialog.ShowDialog() == true)
    18                     {
    19                         //读取文件流
    20                         using (Stream fs = fileDialog.File.OpenRead())
    21                         {
    22                             ReadTxtFile(fs);
    23                             fs.Close();
    24                         }
    25                     }
    26                 });
    27             }
    28             catch (Exception e)
    29             {
    30 
    31                 //错误处理
    32             }
    33         }

    注: 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",
                                                        resTipInformation.strApplicationTitle);
                                }
    
                                //App.Current.MainWindow.TopMost = true;
                            }
                            else
                            {
                                MessageWindow.CreateNew("您好,您已在本机安装了模块程序,请保存本页面数据后双击运行桌面的图标。",
                                                        resTipInformation.strApplicationTitle);
                            }
                        }
                        else
                        {
                            MessageWindow.CreateNewConfirm("打开文档之前需要安装本程序在您电脑上,确定帮您安装吗?为避免数据丢失,请确认前先保存数据。",
                                resTipInformation.strApplicationTitle, () =>
                                {
                                    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

     1         /// <summary>
     2         /// 一行行地循环读取
     3         /// </summary>
     4         private void ReadTxtFile(Stream fs)
     5         {
     6             var myTable = new List<string>();
     7             using (StreamReader reader = new StreamReader(fs, new Gb2312Encoding()))
     8             {
     9                 /*
    10                  * 一次性读出所有文件信息
    11                  * var fileText = string.Empty;
    12                 fileText = reader.ReadToEnd();
    13                  */
    14 
    15                 reader.BaseStream.Seek(0, SeekOrigin.Begin);
    16                 string strLine = reader.ReadLine();
    17                 var tableIndex = 0;
    18                 while (strLine != null)
    19                 {
    20                     /*
    21                      * do your things here
    22                     if (strLine.Contains("[Your message is here]"))
    23                     {
    24                         //找到表头了
    25                         tableIndex++;
    26                     }
    27 
    28                     if (tableIndex > 6)
    29                     {
    30                         //读完需要的表信息了,跳出
    31                         break;
    32                     }
    33 
    34                     if (tableIndex >= 4)
    35                     {
    36                         //开始获取需要的信息
    37                         myTable.Add(strLine);
    38                     }
    39                     if (tableIndex > 0)
    40                     {
    41                         tableIndex++;
    42                     }
    43                     */
    44                     strLine = reader.ReadLine();
    45                 }
    46                 reader.Close();
    47             }
    48 
    49             if (myTable.Any())
    50             {
    51                 foreach (var strItem in myTable)
    52                 {
    53                     var view = strItem.TrimEnd('\t').Split('\t');
    54                     //do something here
    55                 }
    56             }
    57 
    58         }

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

    StreamReader reader = new StreamReader(fs, new Gb2312Encoding())
    Gb2312Encoding的代码,里面包含了个Gb2312toUnicodeDictinary(这个是网上找的,很多网上资料只有Gb2312Encoding,却没有附上Gb2312toUnicodeDictinary)。
    只上Gb2312Encoding的代码吧,Gb2312toUnicodeDictinary有7000多行的说……,这两个文件以附件形式放在后面,有需要的童鞋自行下载。
     1  public class Gb2312Encoding : Encoding
     2     {
     3         public override string WebName
     4         {
     5             get
     6             {
     7                 return "gb2312";
     8             }
     9         }
    10 
    11         public Gb2312Encoding()
    12         {
    13 
    14         }
    15         public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
    16         {
    17             throw new NotImplementedException();
    18         }
    19 
    20         public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
    21         {
    22             int j = 0;
    23             char c;
    24             for (int i = 0; i < byteCount; i += 2)
    25             {
    26                 if (i + 1 >= bytes.Length)
    27                 {
    28                     char[] last = Encoding.UTF8.GetChars(new byte[] { bytes[i] });
    29                     chars[j] = last[0];
    30                 }
    31                 else
    32                 {
    33                     byte[] bb = new byte[] { bytes[i], bytes[i + 1] };
    34                     if (Gb2312toUnicodeDictinary.TryGetChar(bb, out c))
    35                     {
    36                         chars[j] = c;
    37                         j++;
    38                     }
    39                     else
    40                     {
    41                         char[] tt = Encoding.UTF8.GetChars(new byte[] { bb[1] });
    42                         chars[j] = tt[0];
    43                         j++;
    44                         //测试下一个
    45                         if (i + 2 >= bytes.Length)
    46                         {
    47                             char[] tttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
    48                             chars[j] = tttt[0];
    49                             j++;
    50                         }
    51                         else
    52                         {
    53                             byte[] test = new byte[] { bb[0], bytes[i + 2] };
    54                             if (Gb2312toUnicodeDictinary.TryGetChar(test, out c))
    55                             {
    56                                 chars[j] = c;
    57                                 j++;
    58                                 i++;
    59                             }
    60                             else
    61                             {
    62                                 char[] ttt = Encoding.UTF8.GetChars(new byte[] { bb[0] });
    63                                 chars[j] = ttt[0];
    64                                 j++;
    65                             }
    66 
    67                         }
    68                     }
    69                 }
    70             }
    71 
    72             return chars.Length;
    73         }
    74 
    75         public override int GetByteCount(char[] chars, int index, int count)
    76         {
    77             return count;
    78         }
    79         public override int GetCharCount(byte[] bytes, int index, int count)
    80         {
    81             return count;
    82         }
    83 
    84         public override int GetMaxByteCount(int charCount)
    85         {
    86             return charCount;
    87         }
    88         public override int GetMaxCharCount(int byteCount)
    89         {
    90             return byteCount;
    91         }
    92         public static int CharacterCount
    93         {
    94             get { return 7426; }
    95         }
    96     }
    View Code

     附件(GB2312Encoding+GB2312toUnicodeDictinary)下载

    作者:Ivan
    个人网站:http://www.IvanBy.com
  • 相关阅读:
    opencv中的cv::KeyPoint和cv::DMatch
    Spring Security
    错误习题笔记
    Kubernetes 权威指南 深入掌握Service
    Maven 仓库解析
    DDD学习思考记录
    安卓手机mitmproxy抓包
    小米8root
    Linux下快速删除大量文件
    Ubuntu修改主机名和查看主机名的方法
  • 原文地址:https://www.cnblogs.com/oneivan/p/3089503.html
Copyright © 2020-2023  润新知