c# 读txt出现乱码的处理方式

用System.IO.StreamReader读取包含汉字的txt文件时,经常会读出乱码(StreamWriater写文本文件也有类似的问题),原因很简单,就是文件的编码(encoding)和StreamReader/Writer的encoding不对应。为了解决这个问题,我写了一个类,来取得一个文本文件的encoding,这样我们就可以创建对应的StreamReader和StreamWrite来读写,保证不会出现乱码现象。其实原理很简单,文本编辑器(比如XP自带的记事本)在生成文本文件时,如果编码格式和系统默认的编码(中文系统下默认为GB2312)不一致时,会在txt文件开头部分添加特定的“编码字节序标识(Encoding Bit Order Madk,简写为BOM)”,类似PE格式的"MZ"文件头。这样它在读取时就可以根据这个BOM来确定该文本文件生成时所使用的Encoding。这个BOM我们用记事本等程序打开默认是看不到的,但是用stream按字节读取时是可以读到的。我的这个TxtFileEncoding类就是根据这个BOM“文件头”来确定txt文件生成时用到的编码的。
 1 /// <summary>
 2     /// 获取文本文件的编码方式
 3     /// </summary>
 4     class TxtFileEncoding
 5     {
 6         public TxtFileEncoding(){}
 7 
 8         /// <summary>
 9         /// 获取文本文件的编码方式
10         /// </summary>
11         /// <param name="fileName"> 文件名 例如:path = @"D:\test.txt"</param>
12         /// <returns>返回编码方式</returns>
13         public static Encoding GetEncoding(string fileName )
14         {
15             return GetEncoding(fileName, Encoding.Default);
16         }
17 
18         /// <summary>
19         /// 获取文本流的编码方式
20         /// </summary>
21         /// <param name="fs">文本流</param>
22         /// <returns>返回系统默认的编码方式</returns>
23         public static Encoding GetEncoding(FileStream fs)
24         {
25             //Encoding.Default 系统默认的编码方式
26             return GetEncoding(fs, Encoding.Default);
27         }
28 
29         /// <summary>
30         /// 获取一个文本流的编码方式
31         /// </summary>
32         /// <param name="fileName">文件名</param>
33         /// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
34         /// <returns></returns>
35         public static Encoding GetEncoding(string fileName, Encoding defaultEncoding)
36         {
37             FileStream fs = File.Open(fileName,FileMode.Open);
38             Encoding targetEncoding = GetEncoding(fs, defaultEncoding);
39             fs.Close();
40             return targetEncoding;
41         }
42 
43         /// <summary>
44         /// 获取一个文本流的编码方式
45         /// </summary>
46         /// <param name="fs">文本流</param>
47         /// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
48         /// <returns></returns>
49         public static Encoding GetEncoding(FileStream fs, Encoding defaultEncoding)
50         {
51             Encoding targetEncoding = defaultEncoding;
52             if (fs != null && fs.Length >= 2)
53             {
54                 byte b1 = 0;
55                 byte b2 = 0;
56                 byte b3 = 0;
57                 byte b4 = 0;
58 
59                 long oriPos = fs.Seek(0, SeekOrigin.Begin);
60                 fs.Seek(0, SeekOrigin.Begin);
61 
62                 b1 = Convert.ToByte(fs.ReadByte());
63                 b2 = Convert.ToByte(fs.ReadByte());
64                 if (fs.Length > 2)
65                 {
66                     b3 = Convert.ToByte(fs.ReadByte());
67                 }
68                 if (fs.Length > 3)
69                 {
70                     b4 = Convert.ToByte(fs.ReadByte());
71                 }
72 
73                 //根据文件流的前4个字节判断Encoding
74                 //Unicode {0xFF, 0xFE};
75                 //BE-Unicode {0xFE, 0xFF};
76                 //UTF8 = {0xEF, 0xBB, 0xBF};
77                 if (b1 == 0xFE && b2 == 0xFF)//UnicodeBe
78                 {
79                     targetEncoding = Encoding.BigEndianUnicode;
80                 }
81                 if (b1 == 0xFF && b2 == 0xFE && b3 != 0xFF)//Unicode
82                 {
83                     targetEncoding = Encoding.Unicode;
84                 }
85                 if (b1 == 0xEF && b2 == 0xBB && b3 == 0xBF)//UTF8
86                 {
87                     targetEncoding = Encoding.UTF8;
88                 }
89 
90                 fs.Seek(0, SeekOrigin.Begin);
91             }
92             fs.Close();
93             return targetEncoding;
94         }
95     }

 

 

转载于:https://www.cnblogs.com/wasim/p/4910412.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以尝试使用以下代码来取包含文的CSV文件,并解决乱码问题: ```csharp using System; using System.Collections.Generic; using System.IO; using System.Text; public class CsvReader { private string filePath; private string delimiter; public CsvReader(string filePath, string delimiter = ",") { this.filePath = filePath; this.delimiter = delimiter; } public List<List<string>> ReadCsvFile() { List<List<string>> csvData = new List<List<string>>(); using (var reader = new StreamReader(filePath, Encoding.Default)) { while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(delimiter); List<string> row = new List<string>(); foreach (var value in values) { row.Add(value); } csvData.Add(row); } } return csvData; } } public class Program { public static void Main(string[] args) { string filePath = "your_file_path.csv"; CsvReader csvReader = new CsvReader(filePath); List<List<string>> csvData = csvReader.ReadCsvFile(); // 打印CSV文件内容 foreach (var row in csvData) { foreach (var value in row) { Console.Write(value + "\t"); } Console.WriteLine(); } } } ``` 在上述代码,我们使用了 `StreamReader` 类来取CSV文件,并使用 `Encoding.Default` 来指定默认的编码。如果你的CSV文件采用其他编码方式,你可以根据实际情况进行调整。 请将 `your_file_path.csv` 替换为你的CSV文件的实际路径。此代码将CSV文件的内容打印到控制台,你可以根据需要进行后续处理。 希望这可以帮助到你!如果你有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值