准备使用
最好的肯定是现在头部声明要用文件相关的命名空间:
using System.IO;
不用也可以,不过之后想用这个类就需要这样写:
System.IO.StreamReader sr = new System.IO.StreamReader("file.txt");
这样子写起来太长了,为了效率,我们还是在头部写上吧。
了解 Stream (流)
Stream 在计算机里指的是“数据流”,简称“流”。
数据从网盘流到电脑的磁盘里,从 USB 接口流到 U 盘里,从无限路由器的天线流到手机的闪存里… 数据流动就像一条又一条的河流,有方向的从 A 点流到 B 点,所以才称之为 Stream(流)。
如果深入了解,你会发现所有设备都是存在数据流的,包括显示器接收来自电脑的显示信息数据,键盘鼠标输入给计算机的数据流。也就是说,任何数据流动都可以称之为数据流。
开始简单的读写
开始就先了解最基本的操作(System.IO.File 类 和 FileStream 类)
写入
这条程序将会新建一个名为“test.txt”的文本文档,写入“这是一个写入测试”的文本后保存关闭。
static void Main(string[] args)
{
//打开名为"test.txt"的文件,如果不存在就创建一个
FileStream s = File.Open("test.txt", FileMode.OpenOrCreate);
//将文本转码并转换为字节数组保存到变量
byte[] data = Encoding.UTF8.GetBytes("这是一个写入测试");
//向流写入指定数据
s.Write(data, 0, data.Length);
//刷新流,可以理解为确认写入文件,即在调用这个函数之前写入流的内容是不会改变文件的
s.Flush();
//释放并归还资源,不过在正式释放之前也会自行调用一次 Flush()
s.Close();
}
读取
static void Main(string[] args)
{
//打开”test.txt“文件
FileStream s = File.Open("test.txt", FileMode.Open);
//根据流的长度建立一个缓冲区
byte[] d = new byte[s.Length];
//读取流的数据
s.Read(d, 0, (int)s.Length);
//将读取出来的数据进行转码
string outs = Encoding.UTF8.GetString(d);
//向控制台输出
Console.WriteLine(outs);
//释放并归还资源
s.Close();
}
你会发现,每次进行读写操作都需要 byte[] 的介入才可以顺利读写。其实这种情况很正常,标准数据都是按照一个个字节进行存取的, 而C# 作为一门强类型的语言,如果类型不对就无法通过编译。
如果较难理解,那只需要记住:函数要什么你就给什么,给错了谁都别想跑。
关于“缓冲区”:
缓冲区其本质就是在内存空间开辟的一个空间,用于临时存储接收的数据。目的是为了协调低速硬件(磁盘之类)和高速硬件(SRAM、DRAM)之间的通讯而出现。
如果没有缓冲区的话,当低速设备不能及时处理来自高速设备的数据时,高速设备就只能等待低速设备处理完之后才能继续传递数据,从而导致整个系统运行缓慢。若高速设备不等待,就会导致数据丢失。
而将数据先写入到缓冲区,就可以加快系统的运行速度,而且还可以减少对低速设备的 IO 操作,从而提升性能。
以优雅的方式进行读写
觉得 File 类进行读写很麻烦,很反人类?那就试试 StreamReader/StreamWriter 吧,他们具有以下好处:
- 不用设置缓冲区,可以减少一些代码。
- 大多数时候都是使用 string 类型,代表可以少写一些重新编码的代码。
- 里面存在快速操作的函数,简单的场景无需写复杂代码。
优雅的写 (StreamWriter)
static void Main(string[] args)
{
//创建一个名为"test1.txt"的文件,如果文件存在,则清除原来的文件
StreamWriter sw = new StreamWriter("test1.txt");
//向文件写入内容
sw.WriteLine("文本内容");
//释放并归还资源
sw.Close();
}
优雅地读(StreamWriter)
static void Main(string[] args)
{
//尝试打开名为"test.txt"
StreamReader sr = new StreamReader("test.txt");
//读取一行文本内容
string result = sr.ReadLine();
//释放并归还资源
sr.Close();
}
这样读写明显比上面的常规读写更加方便、优雅,但是这种读写局限性比较大,基本上都限制在人写的文本,如果是二进制数据很大概率会出问题。
StreamWriter 和 StreamReader 也可以读写其他类型的数据流,不过按照主题走就先写 FileStream 了。
一句话文件读写
当然有些开发的场景是只需要一次大数据的读写,用上面的方法还是会助长代码的复杂性,有没有什么办法可以一行搞定?
当然有!微软他们已经帮我们想出来了:
File.WriteAllText("test.txt","一次性写入数据"); //就这样一次性写进去
string text = File.ReadAllText("test.txt"); //也可以这样一次性读取文件所有数据
一行搞定一次性读写,非常方便啊!
File 类提供的不只有完全读取,还可以按行读取出 string[] 数组。
同时里面也提供了同样功能,但写入不同数据类型的方法,可以自己试一下看看。
不过场景限制就比较多了,这样子读写就不适合超大文件(大于4G),一般比较适合读取配设文件解析,保存一些较小数据量的文件。
用 Cookie 保存: 别名、Email