源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

解析StreamReader与文件乱码问题的解决方法

  • 时间:2020-08-07 21:14 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:解析StreamReader与文件乱码问题的解决方法
相信很多人在读取文件的时候都会碰到乱码的情况,所谓乱码就是错乱的编码的意思,造成乱码的是由于编码不一致导致的。

[b]演示程序:[/b] [b]新建3个文本文件:[/b] [img]http://files.jb51.net/file_images/article/201305/2013051312072844.jpg[/img] 编码和名字一样,分别是ansi,Unicode,utf8 里面的内容都是: ~@#%……&*()

abcdefg

123456789

测试数据

[img]http://files.jb51.net/file_images/article/201305/2013051312072845.jpg[/img] [img]http://files.jb51.net/file_images/article/201305/2013051312072846.jpg[/img] [img]http://files.jb51.net/file_images/article/201305/2013051312072847.jpg[/img]

 

[b]读取这些文件的代码如下:[/b] public static void Main()

{

    List<string> lstFilePath = new List<string>()

    {

        "H:\\TestText\\ansi.txt",

        "H:\\TestText\\unicode.txt",

        "H:\\TestText\\utf8.txt"

    };

    foreach (string filePath in lstFilePath)

    {

        using (StreamReader reader = new StreamReader(filePath))

        {

            Console.WriteLine("读取文件" + filePath);

            Console.WriteLine(reader.ReadToEnd());

            Console.WriteLine("************************************************************");

        }

    }

}

[b]输出入下:[/b] [img]http://files.jb51.net/file_images/article/201305/2013051312072848.jpg[/img]

 

由于第一个文件使用ansi编码,但是StreamReader 的默认构造函数使用的是utf8编码,所以乱码了。 StreamReader 旨在以一种特定的编码输入字符,而 Stream 类用于字节的输入和输出。 使用 StreamReader 读取标准文本文件的各行信息。

除非另外指定, StreamReader 的默认编码为 UTF-8,而不是当前系统的 ANSI 代码页 UTF-8 可以正确处理 Unicode 字符并在操作系统的本地化版本上提供一致的结果。 所以解决上面的编码问题的解决方案是使用StreamReader,并且传递Encoding.Default作为编码,一般在中文操作系统中,Encoding.Default是Gb2312编码。 public static void Main()

{

    List<string> lstFilePath = new List<string>()

    {

        "H:\\TestText\\ansi.txt",

        "H:\\TestText\\unicode.txt",

        "H:\\TestText\\utf8.txt"

    };

    foreach (string filePath in lstFilePath)

    {

        using (StreamReader reader = new StreamReader(filePath,Encoding.Default))

        {

            Console.WriteLine("读取文件" + filePath);

            Console.WriteLine(reader.ReadToEnd());

            Console.WriteLine("************************************************************");

        }

    }

}

[b]输出如下:

[/b]

[img]http://files.jb51.net/file_images/article/201305/2013051312072849.jpg[/img]

从这里得到一个结论:使用StreamReader,并且使用Encoding.Default 作为编码。

很可惜,上面的这个结论在某些情况下页会存在问题,例如在你的操作系统中Encoding.Default Encoding.UTF8的时候。

最完美的解决方案是:文件使用什么编码保存的,就用什么编码来读取。

[b]那如何得到文件的编码呢?

[/b]

使用下面的代码就可以了:
[u]复制代码[/u] 代码如下:
public static Encoding GetEncoding(string filePath)         {             if (filePath == null)             {                 throw new ArgumentNullException("filePath");             }             Encoding encoding1 = Encoding.Default;             if (File.Exists(filePath))             {                 try                 {                     using (FileStream stream1 = new FileStream(filePath, FileMode.Open, FileAccess.Read))                     {                         if (stream1.Length > 0)                         {                             using (StreamReader reader1 = new StreamReader(stream1, true))                             {                                 char[] chArray1 = new char[1];                                 reader1.Read(chArray1, 0, 1);                                 encoding1 = reader1.CurrentEncoding;                                 reader1.BaseStream.Position = 0;                                 if (encoding1 == Encoding.UTF8)                                 {                                     byte[] buffer1 = encoding1.GetPreamble();                                     if (stream1.Length >= buffer1.Length)                                     {                                         byte[] buffer2 = new byte[buffer1.Length];                                         stream1.Read(buffer2, 0, buffer2.Length);                                         for (int num1 = 0; num1 < buffer2.Length; num1++)                                         {                                             if (buffer2[num1] != buffer1[num1])                                             {                                                 encoding1 = Encoding.Default;                                                 break;                                             }                                         }                                     }                                     else                                     {                                         encoding1 = Encoding.Default;                                     }                                 }                             }                         }                     }                 }                 catch (Exception exception1)                 {                     throw;                 }                 if (encoding1 == null)                 {                     encoding1 = Encoding.UTF8;                 }             }             return encoding1;         }
这段代码使用encoding1.GetPreamble()方法来得到编码的字节序列,然后重新读取数据,比较数据,如果不相同则说明是Encoding.Default.
[b]否则是Encoding.Utf8.

[/b]

有了GetEncoding(filename)方法后,可以将上面的读取代码修改如下:

public static void Main()

{

    List<string> lstFilePath = new List<string>()

    {

        "H:\\TestText\\ansi.txt",

        "H:\\TestText\\unicode.txt",

        "H:\\TestText\\utf8.txt"

    };

    foreach (string filePath in lstFilePath)

    {

        using (StreamReader reader = new StreamReader(filePath, GetEncoding(filePath)))

        {

            Console.WriteLine("读取文件" + filePath);

            Console.WriteLine(reader.ReadToEnd());

            Console.WriteLine("当前编码:" + reader.CurrentEncoding.EncodingName);

            Console.WriteLine("************************************************************");

        }

    }

}

[b]输出如下:

[/b]

[img]http://files.jb51.net/file_images/article/201305/2013051312072852.jpg[/img]

从这里可以看到ansi 编码,Encoding.Default 就是简体中文(GB2312)

  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部