C# WPF Cookie Clicker项目多数据保存加载问题求助
我正在为学校项目制作Cookie Clicker,但不知道如何在C# WPF程序中正确保存和加载多个数据。以下是我编写的保存/加载数据代码,希望能得到帮助:
private void btnSave_Click(object sender, RoutedEventArgs e) { var OpgeslagenData = "opslag.txt"; using(StreamWriter sw = File.CreateText(OpgeslagenData)) { sw.WriteLine(globaleDingen.koekjes); sw.WriteLine(globaleDingen.aantalUpgraded); sw.WriteLine(globaleDingen.klick); sw.WriteLine(globaleDingen.upgrade); sw.WriteLine(globaleDingen.goldBars); } } private void btnLoad_Click(object sender, RoutedEventArgs e) { int koekjes; int aantalUpgraded; int klick; int upgrade; int goldBars; var OpgeslagenData = "opslag.txt"; using(StreamReader sr = File.OpenText(OpgeslagenData)) { koekjes = Convert.ToInt32(sr.ReadLine().ElementAt(1)); aantalUpgraded = Convert.ToInt32(sr.ReadLine().ElementAt(2)); klick = Convert.ToInt32(sr.ReadLine().ElementAt(3)); upgrade = Convert.ToInt32(sr.ReadLine().ElementAt(4)); goldBars = Convert.ToInt32(sr.ReadLine().ElementAt(5)); } globaleDingen.koekjes = koekjes; globaleDingen.aantalUpgraded = aantalUpgraded; globaleDingen.klick = klick; globaleDingen.upgrade = upgrade; globaleDingen.goldBars = goldBars; }
现有代码核心问题
加载逻辑里的sr.ReadLine().ElementAt(n)是完全错误的:
sr.ReadLine()读取的是整行文本(比如你保存的数字100,整行就是字符串"100")ElementAt(n)是取字符串的第n个字符,比如"100".ElementAt(1)会得到'0',转成int后完全不是你要的原始数值
另外代码未处理文件不存在的情况,加载时如果存档丢失会直接抛出异常。
修正后的纯文本读写版本
保留原有的纯文本存储方式,修复加载逻辑并增加异常处理:
private void btnLoad_Click(object sender, RoutedEventArgs e) { var OpgeslagenData = "opslag.txt"; // 先检查文件是否存在 if (!File.Exists(OpgeslagenData)) { // 可选:提示用户存档不存在,或使用默认初始值 return; } using(StreamReader sr = File.OpenText(OpgeslagenData)) { // 用int.TryParse避免转换失败报错,直接读取整行内容 globaleDingen.koekjes = int.TryParse(sr.ReadLine(), out var temp) ? temp : 0; globaleDingen.aantalUpgraded = int.TryParse(sr.ReadLine(), out temp) ? temp : 0; globaleDingen.klick = int.TryParse(sr.ReadLine(), out temp) ? temp : 0; globaleDingen.upgrade = int.TryParse(sr.ReadLine(), out temp) ? temp : 0; globaleDingen.goldBars = int.TryParse(sr.ReadLine(), out temp) ? temp : 0; } // 加载完成后同步更新UI控件 txtKoekjes.Text = globaleDingen.koekjes.ToString(); // 其他界面控件同理更新 }
保存方法可优化存储路径,避免用户误删:
private void btnSave_Click(object sender, RoutedEventArgs e) { // 将存档放到系统应用数据目录,更安全 var saveDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CookieClickerSchoolProject"); Directory.CreateDirectory(saveDir); var OpgeslagenData = Path.Combine(saveDir, "opslag.txt"); using(StreamWriter sw = File.CreateText(OpgeslagenData)) { sw.WriteLine(globaleDingen.koekjes); sw.WriteLine(globaleDingen.aantalUpgraded); sw.WriteLine(globaleDingen.klick); sw.WriteLine(globaleDingen.upgrade); sw.WriteLine(globaleDingen.goldBars); } }
更推荐的方案:JSON序列化
纯文本行存储易因行顺序错乱导致数据错误,推荐用JSON序列化,结构稳定且易于扩展:
- 先定义明确的数据类:
public class GameSaveData { public int koekjes { get; set; } public int aantalUpgraded { get; set; } public int klick { get; set; } public int upgrade { get; set; } public int goldBars { get; set; } } // 全局数据实例 private GameSaveData globaleDingen = new GameSaveData();
- 保存方法(使用.NET自带的System.Text.Json):
private void btnSave_Click(object sender, RoutedEventArgs e) { var saveDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CookieClickerSchoolProject"); Directory.CreateDirectory(saveDir); var savePath = Path.Combine(saveDir, "save.json"); // 序列化对象为JSON字符串 var jsonContent = JsonSerializer.Serialize(globaleDingen); File.WriteAllText(savePath, jsonContent); }
- 加载方法:
private void btnLoad_Click(object sender, RoutedEventArgs e) { var saveDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CookieClickerSchoolProject"); var savePath = Path.Combine(saveDir, "save.json"); if (!File.Exists(savePath)) { return; } var jsonContent = File.ReadAllText(savePath); // 反序列化回对象,空值时用默认实例 globaleDingen = JsonSerializer.Deserialize<GameSaveData>(jsonContent) ?? new GameSaveData(); // 更新UI控件 txtKoekjes.Text = globaleDingen.koekjes.ToString(); // 其他界面控件同步更新 }
JSON方案优势:
- 数据结构清晰,存档为可读格式,方便调试
- 扩展新字段时只需在类中添加属性,无需修改读写逻辑
- 不会因行顺序错误导致数据错位
内容的提问来源于stack exchange,提问作者Jorn Vandermeeren
相关产品推荐
相关产品推荐

