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)下载

你可能感兴趣的:(silverlight)