StreamReader和中文XP的不匹配,及其乱码的解决

来源:互联网 发布:淘宝兑换虾米会员 编辑:程序博客网 时间:2024/05/01 04:50

按照MSDN,StreamWriter和StreamReader是推荐的文本文件读写类,他们会智能的处理文本格式,大可放轻松。然而,我用起来可一点都不轻松。

问题的出现在于现在这个世界的纯文本文件有太多的编码格式,ANSI、GB2312、Unicode、UTF-8....搞错了格式,打开后就是一堆乱码。

为了推广先进的编码格式,微软设置StreamReader也将不明编码的文件读为UTF-8。StreamWriter默认情况下也按UTF-8格式输出文本,而且,不带BOM(一个提示其他软件文本格式的串)。

但是,我们中文XP的默认编码格式是什么呢?好像是GB2312,反正不是UTF-8。

哦,问题出来了。我用StreamWriter输出了一个文本。再用EXCEL另存为输出了个CSV,也是文本文件。现在你猜StreamReader(使用一条语句的情况下)怎么读这两个文件?

答案是,StreamReader根本无法同时读取这两个文件(在使用一条语句的情况下)。

使用不带参数的StremReader(filename)按说明可以自动判断格式,它也确实正确读取了我用StreamWriter输出的文件。但是,他将EXCEL输出的CSV读成了乱码。

使用参数StreamReader(filename, Encoding.Default),可以正常读出EXCEL输出的CSV文件,可是,他又将我用StreamWriter输出的文件读成了乱码。

我晕死!

怎么办呢?

1、不要使用StreamWriter的默认输出,而是使用StreamWriter(filename,bool,Encoding)这个函数,这个函数将会在输出的文件前添加BOM,这样保证你的文本文件不会被误读。

2、不要依靠StreamReader的自动判断,在读取语句前增加一个判断函数,可以基本消除乱码。

下面是CSDN的孟子E章所写的判断函数(我修改了默认返回的编码)。

        public static Encoding GetEncoding(string filename)
        {
            Encoding result = System.Text.Encoding.Default;
            FileStream file = null;
            try
            {
                file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);

                if (file.CanSeek)
                {
                    //   get   the   bom,   if   there   is   one  
                    byte[] bom = new byte[4];
                    file.Read(bom, 0, 4);

                    //   utf-8  
                    if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
                        result = System.Text.Encoding.UTF8;
                    //   ucs-2le,   ucs-4le,   ucs-16le,   utf-16,   ucs-2,   ucs-4  
                    else if ((bom[0] == 0xff && bom[1] == 0xfe) ||
                    (bom[0] == 0xfe && bom[1] == 0xff) ||
                    (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff))
                        result = System.Text.Encoding.Unicode;
                    //   else   ascii  
                    else
                        result = System.Text.Encoding.Default;
                }
                else
                {
                    //   can't   detect,   set   to   default  
                    result = System.Text.Encoding.Default;
                }

                return result;
            }
            finally
            {
                if (null != file) file.Close();
            }
        }

原创粉丝点击