C# 学习笔记 12:让数据永生 —— 文件操作(File I/O)
开篇:皮皮的“坏档”悲剧
皮皮(Pipi)熬了一整天夜, 终于把他的 RPG 角色练到了 99 级。
他满意地点击了控制台右上角的 X,关掉程序。
第二天,他兴冲冲地打开游戏,准备去秒杀魔王。
系统提示:Lv. 1
空气突然安静了。
皮皮:“😱 我的 99 级呢?我的屠龙刀呢?!”
瓜瓜:“冷静。你昨晚只是把数据存在了内存里。 内存是‘易失性’的,程序一关就清空。
想要存档,得把数据写进——文件。”
📌 一句话真相:
内存 = 临时记忆文件 = 永久记忆

第一关:准备工具箱(System.IO)
文件操作不是魔法,而是标准库。
在 C# 里,它们都住在同一个地方:
using System.IO; // 文件操作必备
就像 LINQ 离不开 System.Linq, **所有文件读写,几乎都离不开 System.IO**。
第二关:新手专属存档术(File 类)
刚入门时,请忽略 FileStream、Buffer 这些高级名词。
C# 早就帮你准备好了“一键存档”方案:
File 静态类
写入文件(WriteAllText)
这是一种覆盖式存档。
string saveData = "Name:Pipi, Lv:99, Hp:5000";// 参数:(文件路径, 内容)// 文件不存在 → 自动创建// 文件已存在 → 直接覆盖File.WriteAllText("save.txt", saveData);Console.WriteLine("存档成功!");
📌 适合:
追加内容(AppendAllText)
如果你在写日志 / 日记, 不想覆盖昨天的记录,而是接着写:
string log = "\n[2023-10-01] 皮皮打败了史莱姆。";File.AppendAllText("gamelog.txt", log);
📌 适合:
第三关:读档术(ReadAllText)
存好了,自然要读。
string content = File.ReadAllText("save.txt");Console.WriteLine("读取存档内容:");Console.WriteLine(content);
简单、直接、一步到位。
防弹衣不能脱(Try / Catch)
如果某天皮皮手滑,把 save.txt 删了呢?
👉 程序会直接抛出 FileNotFoundException。
结论:
所有文件操作,默认都是高危动作
try{string content = File.ReadAllText("save.txt"); Console.WriteLine($"读取成功:{content}");}catch (FileNotFoundException){ Console.WriteLine("没找到存档文件,进入新手教程...");}
📌 文件 + 异常处理 是绑定出现的一组技能。
第四关:路径的迷思(Path)
皮皮突然意识到一个问题:
“save.txt……到底存到哪去了?”
相对路径
"save.txt"
📌 新手最常用,也最容易“找不到文件”。
绝对路径
@"C:\Users\Pipi\Documents\save.txt"
@ 可以避免转义 \
瓜瓜强烈推荐:Path.Combine
不要手写斜杠,尽量用 Path.Combine 来拼接路径。
因为 Windows 用 \,Linux/Mac 用 /。
string path = Path.Combine("C:", "Games", "SaveData", "save.txt");
📌 好处只有一个,但非常重要:
跨平台安全Windows / Linux / Mac 都能跑
第五关:大文件专用模式(流式操作 + using)
File.WriteAllText 的问题只有一个:
它一次性把所有内容丢进内存
如果你要写的是:
👉 就该用 “流” 了。
文件也是要“开门 / 关门”的
现代解决方案:using
using (StreamWriter sw = new StreamWriter("log.txt", true)){ sw.WriteLine("第一行日志"); sw.WriteLine("第二行日志");// 写了一万行……}// 👈 出了这个大括号// C# 自动帮你 Close() + Dispose()// 即使中途报错,也一定会关门
📌 一句话理解 using:
你只管用,善后交给语言
这是写稳定程序的核心习惯之一。
总结:文件操作真正教我们的是什么?
今日战利品
真正的理解是:
文件 ≠ 字符串文件 = 资源
课后思考
现在我们存的还是这种东西:
"Name:Pipi, Lv:99"
但皮皮的背包里是:
List<Item>
难道我要手写:
Item1|Item2|Item3|...
再自己拆?
有没有一种办法,可以:
把对象直接变成文本,再原样读回来?
下期预告
答案是:有,而且是现代开发必备技能。
👉 序列化(JSON Serialization)让对象 ↔ 字符串 像变形术一样自由转换。
存档系统的最后一块拼图,就在下一篇。