解析StreamReader与文件乱码问题的解决方法_C#教程-查字典教程网
解析StreamReader与文件乱码问题的解决方法
解析StreamReader与文件乱码问题的解决方法
发布时间:2016-12-28 来源:查字典编辑
摘要:相信很多人在读取文件的时候都会碰到乱码的情况,所谓乱码就是错乱的编码的意思,造成乱码的是由于编码不一致导致的。演示程序:新建3个文本文件:编...

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

演示程序:

新建3个文本文件:

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

里面的内容都是:

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

abcdefg

123456789

测试数据

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

public static void Main()

{

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

{

"H:TestTextansi.txt",

"H:TestTextunicode.txt",

"H:TestTextutf8.txt"

};

foreach (string filePath in lstFilePath)

{

using (StreamReader reader = new StreamReader(filePath))

{

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

Console.WriteLine(reader.ReadToEnd());

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

}

}

}

输出入下:

由于第一个文件使用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:TestTextansi.txt",

"H:TestTextunicode.txt",

"H:TestTextutf8.txt"

};

foreach (string filePath in lstFilePath)

{

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

{

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

Console.WriteLine(reader.ReadToEnd());

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

}

}

}

输出如下:

从这里得到一个结论:使用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:TestTextansi.txt",

"H:TestTextunicode.txt",

"H:TestTextutf8.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("************************************************************");

}

}

}

输出如下:

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

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新C#教程学习
    热门C#教程学习
    编程开发子分类