c#软件开发学习笔记--Winform窗体(本地存储)
·
WinForm学习总结-(本地存储)
一、对象存储与序列化
1.1 对象存储的必要性
- 对象存在于内存中,程序关闭后会被GC回收
- 需要将对象状态持久化到磁盘,以便下次运行时恢复
1.2 简单文本存储方式
直接将对象属性写入文本文件,按行或分隔符区分:
public class People
{
public string Name { get; set; }
public string Age { get; set; }
public string Sex { get; set; }
public string Phone { get; set; }
}
// 写入对象
private void button1_Click(object sender, EventArgs e)
{
People p = new People()
{
Name = textBox1.Text,
Age = textBox2.Text,
Sex = textBox3.Text,
Phone = textBox4.Text
};
FileStream fs = new FileStream(@"1.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(p.Name);
sw.WriteLine(p.Age);
sw.WriteLine(p.Sex);
sw.WriteLine(p.Phone);
sw.Close();
fs.Close();
}
// 读取对象
private void button2_Click(object sender, EventArgs e)
{
People p1 = new People();
using (FileStream fs = new FileStream(@"1.txt", FileMode.Open))
{
StreamReader sr = new StreamReader(fs);
p1.Name = sr.ReadLine();
p1.Age = sr.ReadLine();
p1.Sex = sr.ReadLine();
p1.Phone = sr.ReadLine();
}
textBox1.Text = p1.Name;
}
缺点:
- 读取顺序必须与写入顺序一致,否则数据错乱
- 属性较多时难以维护
- 无法直接识别数据结构
1.3 序列化与反序列化概念
| 概念 | 说明 |
|---|---|
| 序列化 | 将对象状态转换为可保存或传输的格式(二进制、XML、JSON等) |
| 反序列化 | 将序列化后的格式转换回对象 |
二、二进制序列化
2.1 实现步骤
- 在类上添加
[Serializable]特性 - 使用
BinaryFormatter进行序列化和反序列化
2.2 代码示例
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Student
{
public string Name { get; set; }
public string Phone { get; set; }
}
public partial class Form1 : Form
{
List<Student> list = new List<Student>();
public Form1()
{
InitializeComponent();
// 反序列化加载已有数据
FileStream fs = new FileStream(@"1.txt", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
List<Student> temp = bf.Deserialize(fs) as List<Student>;
list.AddRange(temp);
fs.Close();
}
// 序列化写入
private void button1_Click(object sender, EventArgs e)
{
Student stu = new Student()
{
Name = "张三",
Phone = "123456"
};
list.Add(stu);
FileStream fs = new FileStream(@"1.txt", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, list);
fs.Close();
}
// 反序列化读取
private void button2_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(@"1.txt", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
List<Student> ss = bf.Deserialize(fs) as List<Student>;
string s = "";
foreach (var item in ss)
{
s += item.Name + ":" + item.Phone;
}
this.Text = s;
fs.Close();
}
}
2.3 特点
- 优点:存储效率高、速度快、支持复杂对象
- 缺点:文件不可读、版本兼容性差、仅限.NET平台
三、JSON序列化
3.1 JSON格式简介
JSON(JavaScript Object Notation)是轻量级数据交换格式:
// 单个对象
{"Name":"张三","Age":18,"Sex":"男"}
// 对象数组
[{"Name":"张三","Age":18},{"Name":"李四","Age":20}]
语法规则:
[]表示数组{}表示对象- 属性名必须加双引号
- 属性值不能是函数
- 最后一个属性后不能加逗号
3.2 原生方式 - DataContractJsonSerializer
需要引用 System.Runtime.Serialization 程序集:
using System.IO;
using System.Runtime.Serialization.Json;
public class People
{
public string Name { get; set; }
public string Age { get; set; }
public string Sex { get; set; }
}
// 序列化写入
private void button1_Click(object sender, EventArgs e)
{
People p1 = new People()
{
Name = textBox1.Text,
Age = textBox2.Text,
Sex = textBox3.Text,
};
FileStream fs = new FileStream(@"1.txt", FileMode.Create);
DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(People));
ds.WriteObject(fs, p1);
fs.Close();
}
// 反序列化读取
private void button2_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(@"1.txt", FileMode.Open);
DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(People));
People p1 = (People)ds.ReadObject(fs);
fs.Close();
this.Text = p1.Name;
}
3.3 第三方方式 - Newtonsoft.Json (Json.NET)
这是最常用的JSON处理库,功能强大且易用。
安装方式:
- 右键项目 → 管理NuGet程序包 → 搜索
Newtonsoft.Json→ 安装
代码示例:
using Newtonsoft.Json;
using System.IO;
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Info { get; set; }
}
public partial class Form1 : Form
{
List<Student> list = new List<Student>();
public Form1()
{
InitializeComponent();
// 初始化测试数据
for (int i = 0; i < 10; i++)
{
list.Add(new Student()
{
Name = "哈兰德" + i,
Age = i * 10,
Info = "前锋"
});
}
}
// 序列化
private void button1_Click(object sender, EventArgs e)
{
string data = JsonConvert.SerializeObject(list);
File.WriteAllText(@"1.txt", data);
}
// 反序列化
private void button2_Click(object sender, EventArgs e)
{
string data = File.ReadAllText(@"1.txt");
List<Student> students = JsonConvert.DeserializeObject<List<Student>>(data);
string result = "";
foreach (var item in students)
{
result += item.Name;
}
this.Text = result;
}
}
3.4 复杂JSON解析
对于复杂JSON结构,需要根据JSON格式定义对应的类:
// 假设JSON格式:{"hits":{"topicMessageList":[{"author_name":"xxx","cover_image_url":"xxx"}]}}
public class XiaoShuoRoot
{
public Hits hits { get; set; }
}
public class Hits
{
public List<TopicMessageList> topicMessageList { get; set; }
}
public class TopicMessageList
{
public string author_name { get; set; }
public string cover_image_url { get; set; }
}
// 解析复杂JSON
private void button3_Click(object sender, EventArgs e)
{
string data = File.ReadAllText(@"漫画.txt", Encoding.Default);
XiaoShuoRoot root = JsonConvert.DeserializeObject<XiaoShuoRoot>(data);
foreach (var item in root.hits.topicMessageList)
{
richTextBox1.Text += item.author_name + "\n";
}
}
四、XML操作
4.1 XML格式简介
XML(eXtensible Markup Language)是可扩展标记语言:
<?xml version="1.0" encoding="utf-8" ?>
<Students>
<Student>
<StuName>高启强</StuName>
<StuAge>48</StuAge>
<StuGender>男</StuGender>
<StuClass>C#一班</StuClass>
</Student>
</Students>
格式要求:
- 必须有唯一的根元素
- 标签必须正确闭合
- 元素必须正确嵌套
- 属性值必须用引号括起来
4.2 XML序列化
using System.IO;
using System.Xml.Serialization;
public class People
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
}
// 序列化
public void ToXML()
{
People people = new People()
{
Name = "吴亦凡",
Age = 18,
Sex = "男"
};
FileStream fs = new FileStream("1.xml", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
XmlSerializer serializer = new XmlSerializer(typeof(People));
serializer.Serialize(sw, people);
sw.Close();
fs.Close();
}
// 反序列化
public void FromXML()
{
FileStream fs = new FileStream("1.xml", FileMode.Open);
StreamReader sr = new StreamReader(fs);
XmlSerializer serializer = new XmlSerializer(typeof(People));
People people = serializer.Deserialize(sr) as People;
Console.WriteLine(people.Name);
}
4.3 XML文档操作(XmlDocument)
using System.Xml;
private void button1_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"XMLFile1.xml");
XmlNode rootNode = xmlDoc.DocumentElement;
foreach (XmlNode node in rootNode.ChildNodes)
{
if (node.Name == "Student")
{
Student student = new Student();
foreach (XmlNode childNode in node.ChildNodes)
{
switch (childNode.Name)
{
case "StuName":
student.StuName = childNode.InnerText;
break;
case "StuAge":
student.StuAge = int.Parse(childNode.InnerText);
break;
}
}
}
}
}
4.4 XmlDocument常用属性与方法
| 对象 | 属性/方法 | 说明 |
|---|---|---|
XmlDocument |
DocumentElement |
获取根节点 |
XmlDocument |
ChildNodes |
获取所有子节点 |
XmlDocument |
Load() |
加载XML文件 |
XmlNode |
InnerText |
获取节点内容 |
XmlNode |
Name |
获取节点名称 |
XmlNode |
ChildNodes |
获取子节点集合 |
七、INI文件操作
7.1 INI文件格式
INI是Windows传统配置文件格式:
[Database]
Server=127.0.0.1
Port=3306
Username=root
Password=123456
[Logging]
Level=INFO
File=/var/log/myapp.log
[相机1]
曝光=50
亮度=100
特点:
- 由节(Section)和键值对组成
- 所有值都是字符串类型
- 结构简单,易于维护
7.2 INI文件读写实现
通过调用Windows API实现INI文件操作:
using System.Runtime.InteropServices;
using System.Configuration;
public class FileIni
{
private static string filePath = ConfigurationManager.AppSettings["InIFilePath"].ToString();
// 写入INI文件
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WritePrivateProfileString(
string lpAppName,
string lpKeyName,
string lpString,
string lpFileName
);
// 读取INI文件
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
StringBuilder lpReturnedString,
uint nSize,
string lpFileName
);
/// <summary>
/// 写入INI文件
/// </summary>
/// <param name="section">节名称</param>
/// <param name="key">键名</param>
/// <param name="value">键值</param>
public static void Write(string section, string key, string value)
{
WritePrivateProfileString(section, key, value, filePath);
}
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="section">节名称</param>
/// <param name="key">键名</param>
/// <returns>键值</returns>
public static string Read(string section, string key)
{
StringBuilder sb = new StringBuilder();
GetPrivateProfileString(section, key, "", sb, 255, filePath);
return sb.ToString();
}
}
7.3 App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="InIFilePath" value="config.ini" />
</appSettings>
</configuration>
八、CSV文件操作
8.1 CSV格式简介
CSV(Comma Separated Values)是逗号分隔的纯文本格式:
姓名,年龄,性别
小明,20,男
小红,18,女
小华,19,女
8.2 CSV读写示例
using System.IO;
// 写入CSV
private void WriteCSV()
{
List<string> lines = new List<string>();
lines.Add("姓名,年龄,性别");
lines.Add("小明,20,男");
lines.Add("小红,18,女");
File.WriteAllLines("data.csv", lines, Encoding.Default);
}
// 读取CSV
private void ReadCSV()
{
string[] lines = File.ReadAllLines("data.csv", Encoding.Default);
foreach (string line in lines)
{
string[] values = line.Split(',');
string name = values[0];
int age = int.Parse(values[1]);
string sex = values[2];
}
}
九、序列化方式对比
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 二进制序列化 | 效率高、支持复杂对象 | 文件不可读、版本兼容差 | 程序内部数据持久化 |
| JSON序列化 | 轻量、跨平台、可读性好 | 需要第三方库 | 数据交换、API接口 |
| XML序列化 | 结构化、跨平台、可扩展 | 体积大、解析慢 | 配置文件、WebService |
| INI文件 | 结构简单、易于维护 | 功能有限、无类型 | 应用程序配置 |
| CSV文件 | 通用、兼容性好 | 无结构信息 | 表格数据、数据导出 |
更多推荐
所有评论(0)