目录
[1. 两种常用对话框](#1. 两种常用对话框)
[二、方案 1:手动 IO 读写存储对象(简单少量数据)](#二、方案 1:手动 IO 读写存储对象(简单少量数据))
[三、方案 2:二进制序列化(原生高性能,存集合首选)](#三、方案 2:二进制序列化(原生高性能,存集合首选))
[四、方案 3:原生 JSON 序列化(System.Runtime.Serialization)](#四、方案 3:原生 JSON 序列化(System.Runtime.Serialization))
[五、方案 4:第三方 Newtonsoft.Json(Json.NET,工业首选)](#五、方案 4:第三方 Newtonsoft.Json(Json.NET,工业首选))
[复杂嵌套 JSON 解析(接口数据场景)](#复杂嵌套 JSON 解析(接口数据场景))
[六、方案 5:XML 序列化 / XML 文档解析](#六、方案 5:XML 序列化 / XML 文档解析)
[方式 1:XmlDocument 手动解析现有 XML](#方式 1:XmlDocument 手动解析现有 XML)
[方式 2:XmlSerializer 对象序列化](#方式 2:XmlSerializer 对象序列化)
一、基础工具:文件对话框(操作本地文件必备)
1. 两种常用对话框
- FolderBrowserDialog:选择本地文件夹,获取文件夹路径
- OpenFileDialog:选择文件,获取文件完整路径
完整代码
cs
using System;
using System.Windows.Forms;
namespace FileDialogDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 选择文件夹按钮
private void btnSelectFolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.Description = "请选择数据保存文件夹";
// 设置对话框默认根目录:公共文档
fbd.RootFolder = Environment.SpecialFolder.CommonDocuments;
if (fbd.ShowDialog() == DialogResult.OK)
{
// 获取选中文件夹完整路径
string path = fbd.SelectedPath;
this.Text = path;
}
}
// 打开文件对话框示例
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "读取本地文本文件";
ofd.InitialDirectory = @"D:\";
// 文件过滤:仅显示txt、jpg
ofd.Filter = "文本文件|*.txt|图片|*.jpg";
if (ofd.ShowDialog() == DialogResult.OK)
{
// 读取文件全部文本
string content = System.IO.File.ReadAllText(ofd.FileName, System.Text.Encoding.Default);
}
}
}
}
知识点说明
ShowDialog()弹出模态窗口,返回DialogResult.OK代表用户确认选择SelectedPath:文件夹对话框专用,拿到文件夹路径FileName:打开文件对话框专用,拿到选中文件完整路径Filter格式:说明|后缀|说明|后缀,用来筛选文件类型
二、方案 1:手动 IO 读写存储对象(简单少量数据)
原理
不使用序列化工具,手动拆分对象每个属性,分行 / 分隔符写入 txt;读取时逐行取出,手动赋值给对象。适合单个简单对象,集合存储维护麻烦。
实体类
cs
public class People
{
public string Name { get; set; }
public string Age { get; set; }
public string Sex { get; set; }
public string Phone { get; set; }
}
窗体读写代码
cs
using System;
using System.IO;
using System.Windows.Forms;
namespace IOObjectSave
{
public partial class Form1 : Form
{
// 写入对象到文件
private void btnSave_Click(object sender, EventArgs e)
{
People p = new People()
{
Name = txtName.Text,
Age = txtAge.Text,
Sex = txtSex.Text,
Phone = txtPhone.Text
};
// 创建文件流 + 文本写入器
using (FileStream fs = new FileStream(@"data.txt", FileMode.Create))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(p.Name);
sw.WriteLine(p.Age);
sw.WriteLine(p.Sex);
sw.WriteLine(p.Phone);
}
}
// 读取文件还原对象
private void btnRead_Click(object sender, EventArgs e)
{
People p = new People();
using (FileStream fs = new FileStream(@"data.txt", FileMode.Open))
using (StreamReader sr = new StreamReader(fs))
{
p.Name = sr.ReadLine();
p.Age = sr.ReadLine();
p.Sex = sr.ReadLine();
p.Phone = sr.ReadLine();
}
// 赋值回输入框
txtName.Text = p.Name;
}
}
}
优缺点
- 优点:无需任何引用、上手简单、文件可读
- 缺点:集合操作繁琐、字段增减要同步改读写代码、扩展性差
三、方案 2:二进制序列化(原生高性能,存集合首选)
核心概念
序列化:对象 / 集合 → 二进制字节写入文件 反序列化:二进制文件 → 内存对象 / 集合
必备条件
实体类必须标记
[Serializable]特性,引入命名空间System.Runtime.Serialization.Formatters.Binary
实体类
cs
using System;
[Serializable] // 标记允许二进制序列化
public class Student
{
public string Name { get; set; }
public string Phone { get; set; }
}
完整窗体代码
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace BinarySerializeDemo
{
public partial class Form1 : Form
{
List<Student> studentList = new List<Student>();
string filePath = @"student.dat";
public Form1()
{
InitializeComponent();
// 窗体加载:读取本地已有集合
if (File.Exists(filePath))
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
List<Student> temp = bf.Deserialize(fs) as List<Student>;
studentList.AddRange(temp);
}
}
}
// 新增对象并序列化保存集合
private void btnSaveList_Click(object sender, EventArgs e)
{
Student stu = new Student() { Name = "张三1", Phone = "1232" };
studentList.Add(stu);
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, studentList); // 序列化写入文件
}
}
// 反序列化读取全部集合
private void btnReadList_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
List<Student> list = bf.Deserialize(fs) as List<Student>;
string msg = "";
foreach (var item in list)
{
msg += $"{item.Name}:{item.Phone} ";
}
this.Text = msg;
}
}
}
}
优缺点
- 优点:速度快、文件体积小、原生无第三方依赖、完美支持 List 集合
- 缺点:二进制文件无法直接打开阅读、跨语言不兼容、.NET 高版本逐渐不推荐
四、方案 3:原生 JSON 序列化(System.Runtime.Serialization)
说明
微软自带 JSON 工具 DataContractJsonSerializer,无需 NuGet,适合简单对象;需要手动添加程序集引用 System.Runtime.Serialization
实体类
cs
public class People
{
public string Name { get; set; }
public string Age { get; set; }
public string Sex { get; set; }
}
读写代码
cs
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Windows.Forms;
namespace NativeJsonDemo
{
public partial class Form1 : Form
{
string path = @"user.txt";
// 对象序列化为JSON写入文件
private void btnSave_Click(object sender, EventArgs e)
{
People p = new People()
{
Name = txtName.Text,
Age = txtAge.Text,
Sex = txtSex.Text
};
using (FileStream fs = new FileStream(path, FileMode.Create))
{
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(People));
json.WriteObject(fs, p);
}
}
// JSON文件反序列化为对象
private void btnRead_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream(path, FileMode.Open))
{
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(People));
People p = (People)json.ReadObject(fs);
this.Text = p.Name;
}
}
}
}
优缺点
- 优点:框架原生自带、JSON 文本可读
- 缺点:API 繁琐、复杂集合 / 嵌套对象兼容性差、开发效率低
五、方案 4:第三方 Newtonsoft.Json(Json.NET,工业首选)
使用步骤
- NuGet 搜索安装
Newtonsoft.Json - 引入命名空间
using Newtonsoft.Json;
优势
一行代码完成序列化 / 反序列化,完美支持对象、List、多层嵌套复杂实体,开发最常用
简单集合示例
cs
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using System.Windows.Forms;
namespace NewtonsoftJsonDemo
{
public partial class Form1 : Form
{
List<Student> studentList = new List<Student>();
string path = @"student.json";
public Form1()
{
InitializeComponent();
// 模拟测试数据
for (int i = 0; i < 10; i++)
{
studentList.Add(new Student()
{
Name = "哈兰德" + i,
Age = i * 10,
Info = "前锋"
});
}
}
// 保存集合到JSON文件
private void btnSave_Click(object sender, EventArgs e)
{
string jsonStr = JsonConvert.SerializeObject(studentList);
File.WriteAllText(path, jsonStr);
}
// 读取JSON还原集合
private void btnRead_Click(object sender, EventArgs e)
{
string json = File.ReadAllText(path);
List<Student> list = JsonConvert.DeserializeObject<List<Student>>(json);
string text = "";
foreach (var item in list) text += item.Name;
this.Text = text;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Info { get; set; }
}
}
复杂嵌套 JSON 解析(接口数据场景)
多层 JSON 对应多层实体,大括号对应类、数组对应 List:
cs
// 分层实体
public class TopicMessageList
{
public string cover_image_url { get; set; }
public string author_name { get; set; }
}
public class Hits
{
public List<TopicMessageList> topicMessageList { get; set; }
}
public class XiaoShuoRoot
{
public int code { get; set; }
public string message { get; set; }
public int total { get; set; }
public Hits hits { get; set; }
}
// 读取本地复杂JSON文件
private void btnLoadData_Click(object sender, EventArgs e)
{
string json = File.ReadAllText(@"漫画.txt", System.Text.Encoding.Default);
XiaoShuoRoot root = JsonConvert.DeserializeObject<XiaoShuoRoot>(json);
foreach (var item in root.hits.topicMessageList)
{
richTextBox1.Text += item.author_name + "\n";
}
}
优缺点
- 优点:API 极简、支持所有数据结构、JSON 可读性强、跨平台通用、调试方便
- 缺点:需要额外安装 NuGet 包
六、方案 5:XML 序列化 / XML 文档解析
两种操作方式:
XmlSerializer:序列化对象直接生成 XML 文件XmlDocument:手动读取 XML 节点,灵活解析自定义 XML 结构
方式 1:XmlDocument 手动解析现有 XML
cs
<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
<Student>
<Name>张三1</Name>
<Age>10</Age>
<Sex>男</Sex>
<Phone>121323232</Phone>
</Student>
</StudentList>
解析代码
cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
namespace XmlDemo
{
public partial class Form1 : Form
{
private void btnReadXml_Click(object sender, EventArgs e)
{
List<Student> list = new List<Student>();
XmlDocument doc = new XmlDocument();
doc.Load(@"../../XMLFile1.xml");
XmlNode root = doc.DocumentElement;
foreach (XmlNode node in root.ChildNodes)
{
if (node.Name == "Student")
{
Student stu = new Student();
foreach (XmlNode child in node.ChildNodes)
{
switch (child.Name)
{
case "Name": stu.Name = child.InnerText; break;
case "Age": stu.Age = int.Parse(child.InnerText); break;
case "Sex": stu.Sex = child.InnerText; break;
case "Phone": stu.Phone = child.InnerText; break;
}
}
list.Add(stu);
}
}
foreach (var s in list) MessageBox.Show(s.Name);
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public string Phone { get; set; }
}
}
方式 2:XmlSerializer 对象序列化
cs
// 写入XML
People p = new People() { Age = 10, Name = "zs" };
using (FileStream fs = new FileStream(@"data.xml", FileMode.Create))
{
XmlSerializer xmlSer = new XmlSerializer(typeof(People));
xmlSer.Serialize(fs, p);
}
// 读取XML还原对象
using (FileStream fs = new FileStream(@"data.xml", FileMode.Open))
{
XmlSerializer xmlSer = new XmlSerializer(typeof(People));
People p = (People)xmlSer.Deserialize(fs);
this.Text = p.Name;
}
public class People
{
public string Name { get; set; }
public int Age { get; set; }
}
优缺点
- 优点:标准标记语言、老式系统通用、配置文件常用
- 缺点:标签冗余文件大、代码冗长、现在新项目基本优先 JSON
六、六种持久化方案选型总结
- 少量简单对象、不想引用第三方:手动 IO 读写
- 追求速度、不要求可读、纯.NET 程序:二进制序列化
- 不想装 NuGet、简单对象存储:原生 DataContractJsonSerializer
- 绝大多数业务、集合 / 嵌套对象、前后端交互:Newtonsoft.Json(推荐)
- 老项目、配置文件、传统系统对接:XML
- 文件路径选择统一搭配:FolderBrowserDialog / OpenFileDialog