一.文件编码简介
1.what is ascil?
American Standard Code For Information美国标准信息码,是基于拉丁字母的一套一套电脑编码系统,它主要用于显示现代英语和其他西欧语言.它是现今最通用的
单字节编码系统.(一共256ascil码,只能表示16个大小些字母及数字等符号)
■因为ascil只能表示有限的字符,比如无法表示中文等字符
2.What is unicode?
采用双字节进行编码;统一的字符编码标准.又称为万国码,统一字符标准统一码,是业界的一种标准.
我们需要注意的是:unicode只是一个字符集,它只规定了符号的二进制代码,却没有规定这个二进制代码如何存储.
3.UTF(通用转换格式)编码
UTF,是Unicode Transformation Format的缩写,意为Unicode转换格式.
#region 循环显示字符 for (int i = 0; i < int.MaxValue; i++) { char ch = (char)i; Console.WriteLine(ch); } #endregion
从上述代码得知:每一个数字都对应一个unicode编码,在我们的电脑上显示的字符是中文的,那么则存在一对应的编码格式,使之对应不同国家的字符.
前面 我们学习的读取文件的代码:System.Io.File.Read("1.txt",Encoding.Default)
其中 Encoding.Default就表示一个默认的获得操作系统的当前ANSI代码页的编码
#region 关于Encoding EncodingInfo[] c = Encoding.GetEncodings();//返回所有包含编码的数组 for (int i = 0; i < c.Length; i++) { Console.WriteLine(c[i].Name + "\ " + c[i].CodePage + "\ " + c[i].DisplayName); } #endregion
控制台打印的结果为(截取最后面的部分,包含了中文对应的编码)
中文编码为gb2312
4.读取正确字符串:
string str=System.IO.File.ReadAllText("弈情.txt"); //读出的字符串为乱码,因为没有指定编码格式
(1)微软vs默认的编码为utf-8,而我们的弈情.txt文本为当前的ASNI格式存储的,所以我们可以将弈情.txt存储为utf-8存储格式,这样就可以读出来正确的字符串了.
(2)
string str = System.IO.File.ReadAllText("弈情.txt", Encoding.GetEncoding("gb2312")); //读出的字符串为中文的
(3)
string str1 = System.IO.File.ReadAllText("弈情.txt", Encoding.Default);//默认为电脑系统的即当前ASNI
二.读取文件的类StreamReader System.IO.File.ReadAllLines() System.IO.ReadAllText
StreamReader sr = new StreamReader("弈情.txt", Encoding.GetEncoding("gb2312")); //Console.WriteLine(sr.ReadLine());读取第一行 //Console.WriteLine(sr.ReadLine());读取第二行 //Console.WriteLine(sr.ReadLine());读取第三行 //Console.WriteLine(sr.ReadLine());读取第四行
StreamReader的ReadLine方法每次读一行,并且再次读取的时候,从上次读取的下一行开始,并且当文档读完的时候返回空
所以,我们可以用以下代码实现
string str2 = string.Empty; while((str2=sr.ReadLine())!=null) { Console.WriteLine(str2); }
我们用reflect反编译发现:System.IO.File.ReadAllLines()里面其实就是用StreamReadLines()方法读取没一行,然后用list存储读取的行,并返回list.ToArray()
string[] strs2 = System.IO.File.ReadAllLines("弈情.txt", Encoding.Default);
string str2 = System.IO.File.ReadAllText("弈情.txt", Encoding.Default);
三、写文件
1.WriteAllText WriteAllLines
string[] strs ={@"又看烈阳看秋雨", "昔日情愁似旧曲", "择日时节还难复", "博弈心境堪难举"}; string str1 = "哈哈哈哈哈"; System.IO.File.WriteAllLines(@"D:1.txt", strs); System.IO.File.WriteAllText(@"D:\2.txt",str1);
2.StreamWriter
StreamWriter sw = new StreamWriter("D:\Write进来的文本.txt",false,Encoding.Default);//第二个参数表示追加或者覆盖 using(sw) { Console.WriteLine("请输入要写入的语句"); string strinput = Console.ReadLine(); sw.Write(strinput); sw.WriteLine(strinput);//writeLine比Write写入的字符串要多两个字节,原因是有换行 sw.WriteLine("今天是{0}年{1}月{2}日", 2013, 12, 26); }
单步调试发现,并不是每write一次就会向硬盘写入字符串,而是在sw对象释放之前,一次性将所有字符串都写入硬盘.系统这样设置的原因是避免硬盘反复写入字符而导致坏死.write的时候是将字符串先存在一个高速缓存区.我们常用的迅雷,在下载资源的时候,若将其缓存设置的越大,硬盘保护的越好,但是若中途断网,可能就造成浪费了缓存去已下载的大连数据.
我们可以调用Dispose()方法来回收资源
StreamWriter sw = new StreamWriter("D:\Write进来的文本.txt",false,Encoding.Default); sw.WriteLine("今天是{0}年{1}月{2}日", 2013, 12, 12); sw.Dispose();
单步调试发现,在sw调用Dispose()方法后,才将字符串写入硬盘.若想要手动迅速将数据写入硬盘,可以使用Flush()方法
StreamWriter sw = new StreamWriter("D:\Write进来的文本.txt",false,Encoding.Default); sw.WriteLine("今天是{0}年{1}月{2}日", 2013, 12, 12); sw.Flush(); sw.Dispose();
3.字符串拼接StringBuilder
string[] strs2 = System.IO.File.ReadAllLines("弈情.txt", Encoding.Default); string str2 = ""; for (int i = 0; i < strs2.Length; i++) { str2 += strs2[i]; }
以上拼接字符串,若是弈情.txt这个本文非常大的话,该程序需要执行很久.所以我们采用StringBuilder类
StringBuilder sb = new StringBuilder(); for (int i = 0; i < strs2.Length;i++ ) { sb.Append(strs2[i]);//高效率 }
4.appendAllText
System.IO.File.WriteAllText(@"d:3.txt", sb.ToString()); System.IO.File.AppendAllText(@"d:3.txt", str1);//追加到3.txt文本中
注意:StreamWrite和StreamReader都是非托管对象,它们是实现了IDisposeable接口的资源.GC不会帮我们管理,需要程序员自己回收对象,我们可以用using语句进行资源回收.