[C#] 开始操作文件 (System.IO.File)


准备使用

最好的肯定是现在头部声明要用文件相关的命名空间:

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),一般比较适合读取配设文件解析,保存一些较小数据量的文件。

分组于: 编程

发布于: 2022年12月04日 11时27分

编辑于: 2022年12月04日 11时27分

用 Cookie 保存: 别名、Email