文件读写

一.文件编码简介

1.what is ascil?

American Standard Code For Information美国标准信息码,是基于拉丁字母的一套一套电脑编码系统,它主要用于显示现代英语和其他西欧语言.它是现今最通用的

字节编码系统.(一共256ascil码,只能表示16个大小些字母及数字等符号)

■因为ascil只能表示有限的字符,比如无法表示中文等字符

2.What is unicode?

采用字节进行编码;统一的字符编码标准.又称为万国码,统一字符标准统一码,是业界的一种标准.

我们需要注意的是:unicode只是一个字符集,它只规定了符号的二进制代码,却没有规定这个二进制代码如何存储.

3.UTF(通用转换格式)编码

UTF,是Unicode Transformation Format的缩写,意为Unicode转换格式.

如果UNICODE 字符由2个 字节表示,则编码成UTF-8很可能需要3个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的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语句进行资源回收.

 

原文地址:https://www.cnblogs.com/tobecabbage/p/3490600.html