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

时间:2022-09-11 18:34:56 

相信很多人在读取文件的时候都会碰到乱码的情况,所谓乱码就是错乱的编码的意思,造成乱码的是由于编码不一致导致的。

演示程序:

新建3个文本文件:

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

编码和名字一样,分别是ansi,Unicode,utf8

里面的内容都是:

~!@#¥%……&*()

abcdefg

123456789

测试数据

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

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

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

读取这些文件的代码如下:

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("************************************************************");

        }

    }

}

输出入下:

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

由于第一个文件使用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("************************************************************");

        }

    }

}

输出如下:

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

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

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

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

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

使用下面的代码就可以了:


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.

否则是Encoding.Utf8.

有了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("************************************************************");

        }

    }

}

输出如下:

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

标签:StreamReader,文件乱码
0
投稿

猜你喜欢

  • 自定义视图view使用Canvas实现手写板和涂鸦功能

    2022-02-22 17:00:43
  • C# 线程同步详解

    2021-12-30 04:50:03
  • 简单聊聊c# 事件

    2022-03-05 06:16:52
  • 通过JDK源码学习InputStream详解

    2022-09-10 19:50:29
  • .Net WInform开发笔记(三)谈谈自制控件(自定义控件)

    2021-06-11 10:25:11
  • Android 读取资源文件实例详解

    2022-08-28 13:31:17
  • 基于Android Service 生命周期的详细介绍

    2021-09-11 08:11:42
  • C#集合之队列的用法

    2022-11-24 16:15:38
  • C#使用ICSharpCode.SharpZipLib.dll进行文件的压缩与解压功能

    2022-01-09 15:30:45
  • Android 如何从零开始写一款书籍阅读器的示例

    2022-10-20 17:52:08
  • c#集合快速排序类实现代码分享

    2023-03-30 13:38:51
  • C#静态方法的使用

    2022-05-19 06:45:09
  • 详解SpringBoot配置文件启动时动态配置参数方法

    2022-03-05 03:20:02
  • Spring注解驱动开发实现属性赋值

    2023-05-07 04:40:22
  • 解决logback的日志文件路径问题

    2023-06-13 10:48:09
  • 微信跳一跳辅助Java代码实现

    2022-03-31 19:12:03
  • Java聊天室之实现一个服务器与多个客户端通信

    2021-06-03 11:34:45
  • Android编程画图之抗锯齿解决方法

    2022-12-17 12:03:54
  • IDEA编译报错:Error:java:无效的源发行版:17的解决办法

    2023-08-25 10:38:06
  • Java线程池ThreadPoolExecutor源码深入分析

    2023-11-09 19:49:36
  • asp之家 软件编程 m.aspxhome.com