目录
[一、JSON 序列化 + DataGridView 表格展示](#一、JSON 序列化 + DataGridView 表格展示)
[二、INI 配置文件读写(案例 2)](#二、INI 配置文件读写(案例 2))
[1. App.config 全局配置](#1. App.config 全局配置)
[2. 极简工具类 INITool.cs](#2. 极简工具类 INITool.cs)
[3. 完整底层工具 IniAPI.cs(Tool 公共类库)](#3. 完整底层工具 IniAPI.cs(Tool 公共类库))
[4. 窗体调用示例](#4. 窗体调用示例)
[INI 文件格式规范](#INI 文件格式规范)
[三、CSV 逗号分隔表格文件(案例 3)](#三、CSV 逗号分隔表格文件(案例 3))
[CSVAPI 完整工具类](#CSVAPI 完整工具类)
[CSV 格式规则](#CSV 格式规则)
[四、项目 Settings 用户配置(案例 4)](#四、项目 Settings 用户配置(案例 4))
[底层生成 App.config 配置](#底层生成 App.config 配置)
[五、try-catch 异常捕获(案例 5)](#五、try-catch 异常捕获(案例 5))
一、JSON 序列化 + DataGridView 表格展示
功能说明
- Newtonsoft.Json 反序列化本地 json 文本
- 自定义 DataGridView 列(地址文本、图片、alt 提示)
- 本地路径加载图片绑定表格 Image 列
- 单元格点击调用系统浏览器打开链接
完整代码
cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace _1练习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BindGridView();
BindData();
}
// 手动创建DataGridView列,不自动生成
private void BindGridView()
{
dataGridView1.AutoGenerateColumns = false;
dataGridView1.Columns.Clear();
// 地址文本列
DataGridViewTextBoxColumn colAddr = new DataGridViewTextBoxColumn();
colAddr.HeaderText = "地址";
colAddr.Width = 300;
colAddr.Name = "Address";
colAddr.DataPropertyName = "link";
dataGridView1.Columns.Add(colAddr);
// 图片列
DataGridViewImageColumn colImg = new DataGridViewImageColumn();
colImg.HeaderText = "图片";
colImg.Width = 200;
colImg.Name = "proImage";
colImg.ImageLayout = DataGridViewImageCellLayout.Zoom;
colImg.DataPropertyName = "proImage";
dataGridView1.Columns.Add(colImg);
// 提示文本列
DataGridViewTextBoxColumn colAlt = new DataGridViewTextBoxColumn();
colAlt.HeaderText = "提示";
colAlt.Width = 100;
colAlt.Name = "Alt";
colAlt.DataPropertyName = "alt";
dataGridView1.Columns.Add(colAlt);
dataGridView1.RowTemplate.Height = 80;
}
// 读取json文件、序列化、加载图片绑定表格
private void BindData()
{
string jsonText = File.ReadAllText(@"1.txt", System.Text.Encoding.Default);
Root root = JsonConvert.DeserializeObject<Root>(jsonText);
foreach (var item in root.list)
{
item.proImage = Image.FromFile(item.img_url);
}
dataGridView1.DataSource = root.list;
}
// 单元格点击事件:打开网页链接
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int addrColIndex = dataGridView1.Columns["Address"].Index;
if (e.ColumnIndex == addrColIndex && e.RowIndex >= 0)
{
string url = dataGridView1[addrColIndex, e.RowIndex].Value.ToString();
System.Diagnostics.Process.Start(url);
}
}
}
// JSON映射实体
public class ListData
{
public string link { get; set; }
public string img_url { get; set; }
public string alt { get; set; }
// 内存图片对象,仅用于表格展示,不序列化存文件
public Image proImage { get; set; }
}
public class Root
{
public string title { get; set; }
public List<ListData> list { get; set; }
}
}
核心知识点
DataPropertyName:绑定实体类属性名,实现数据源自动映射单元格DataGridViewImageColumn.ImageLayout.Zoom:图片等比缩放适配单元格Process.Start(url):调用系统默认浏览器打开网址- Newtonsoft.Json:第三方高性能 JSON 序列化库,需 NuGet 安装
- 实体分离:
img_url存文件路径(持久化),proImage内存图片(仅界面展示)
二、INI 配置文件读写(案例 2)
两种封装方案
- 简易
INITool:极简封装,依赖 AppConfig 读取 ini 文件路径 - 完整
IniAPI:封装 Windows 原生 kernel32.dll,支持增删节点、批量读取、数字 / 浮点读取
1. App.config 全局配置
cs
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<appSettings>
<!-- ini文件物理路径 -->
<add key="filePath" value="C:\xxx\bin\Debug\config.ini"/>
</appSettings>
</configuration>
2. 极简工具类 INITool.cs
cs
using System;
using System.Configuration;
using System.Runtime.InteropServices;
using System.Text;
namespace _2_ini文件读写
{
public class INITool
{
// 从配置文件读取ini路径
private static string filePath = ConfigurationManager.AppSettings["filePath"].ToString();
// 引入Windows原生INI写入API
[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);
// 原生读取API
[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>
public static void Write(string section, string key, string value)
{
WritePrivateProfileString(section, key, value, filePath);
}
/// <summary>读取ini指定键值</summary>
public static string Read(string section, string key)
{
StringBuilder sb = new StringBuilder(255);
GetPrivateProfileString(section, key, "", sb, 255, filePath);
return sb.ToString();
}
}
}
3. 完整底层工具 IniAPI.cs(Tool 公共类库)
核心能力:
- 获取全部 Section 节点名
- 获取单个节点下全部 key=value 键值对
- 读取字符串 /int/double 类型配置
- 删除 Key、删除整个节点、清空节点内容
- 批量写入节点多条数据
核心 API 原理:通过DllImport引入kernel32.dll非托管 Windows 原生 INI 操作函数,使用Marshal封送内存缓冲区读取多段\0分隔文本。
4. 窗体调用示例
cs
// 写入
INITool.Write("Address", "serve", textBox1.Text);
INITool.Write("Address", "port", textBox2.Text);
// 读取
textBox1.Text = INITool.Read("Address", "serve");
// 获取节点下所有键值数组
string[] arr = IniAPI.INIGetAllItems(filePath, "Address");
// 删除键
IniAPI.INIDeleteKey(filePath,"Address","port");
// 删除整个节点
IniAPI.INIDeleteSection(filePath,"相机");
INI 文件格式规范
cs
[Address]
serve=127.0.0.1
port=8080
[相机]
曝光=300
[Section]:配置节点(节)key=value:键值对,无空格、区分大小写(API 可自动兼容)
三、CSV 逗号分隔表格文件(案例 3)
适用场景
轻量表格存储,可用 Excel 直接打开,纯文本无依赖,适合导出简单列表数据。
CSVAPI 完整工具类
cs
using System;
using System.IO;
using System.Text;
namespace _3csv数据格式
{
public class CSVAPI
{
// 追加一行数据,自动创建目录、自动写入表头
public static void SaveData(string name, string age, string sex)
{
string dir = Directory.GetCurrentDirectory() + @"\data";
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
string file = dir + @"\1.csv";
// 文件不存在:创建并写入表头
if (!File.Exists(file))
{
using (StreamWriter sw = new StreamWriter(file, false, Encoding.Default))
{
sw.WriteLine("姓名,年龄,性别");
}
}
// 追加数据行
using (StreamWriter sw = new StreamWriter(file, true, Encoding.Default))
{
sw.WriteLine($"{name},{age},{sex}");
}
}
// 读取完整CSV文本
public static string ReadData()
{
string dir = Directory.GetCurrentDirectory() + @"\data";
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
string file = dir + @"\1.csv";
using (StreamReader sr = new StreamReader(file, Encoding.Default))
{
return sr.ReadToEnd();
}
}
}
}
窗体读取解析逻辑
cs
private void button2_Click(object sender, EventArgs e)
{
string allText = CSVAPI.ReadData();
// 按换行分割所有行
string[] lines = allText.Split('\n');
// 跳过表头、跳过末尾空行
for (int i = 1; i < lines.Length - 1; i++)
{
string[] rowData = lines[i].Split(',');
string name = rowData[0];
string age = rowData[1];
string sex = rowData[2];
}
}
CSV 格式规则
- 第一行为表头,逗号分隔字段
- 每行一条数据,字段逗号隔开
- 缺陷:字段内容包含逗号 / 换行时会解析错乱,复杂表格推荐 JSON
示例文件内容:
cs
姓名,年龄,性别
梅西,20,男
张三,25,女
四、项目 Settings 用户配置(案例 4)
特点
- VS 可视化配置,无需手动写 xml
- 分
Application程序级(只读)、User用户级(可运行修改保存) - 自动序列化,支持 string、int、bool、Color 等类型
- 存储路径:C:\Users\ 当前用户 \AppData\Local\ 项目名
使用步骤
- 项目右键 → 属性 → 设置 → 添加 name/age/sex 字段
- 代码读写
cs
// 写入修改
Settings set = Settings.Default;
set.name = "李四";
set.age = 40;
set.sex = true;
set.Save(); // 持久化保存到本地用户配置文件
// 读取
string userName = Settings.Default.name;
底层生成 App.config 配置
cs
<userSettings>
<_4setting读写.Properties.Settings>
<setting name="name" serializeAs="String">
<value>张三</value>
</setting>
<setting name="age" serializeAs="String">
<value>20</value>
</setting>
</_4setting读写.Properties.Settings>
</userSettings>
五、try-catch 异常捕获(案例 5)
核心作用
捕获程序运行错误,避免程序直接崩溃,友好提示错误信息。
分层捕获规则(优先级从上到下)
- 特定细分异常(精准捕获)
FormatException:字符串转数字格式错误OverflowException:数值超出类型范围IndexOutOfRangeException:数组索引越界NullReferenceException:空对象调用属性 / 方法DivideByZeroException:除以 0ArgumentException:传入非法参数
Exception:所有异常基类,兜底捕获,必须放最后
标准模板
cs
try
{
// 可能报错的业务代码
int num = int.Parse(textBox1.Text);
int[] arr = new int[3];
int val = arr[num];
}
catch (FormatException ex)
{
MessageBox.Show("输入不是合法数字:" + ex.Message);
}
catch (IndexOutOfRangeException ex)
{
MessageBox.Show("数组索引超出范围:" + ex.Message);
}
catch (Exception ex)
{
// 未知异常兜底
MessageBox.Show("程序异常:" + ex.Message);
// throw ex; // 抛出异常,终止程序
}
finally
{
// 无论是否报错,一定会执行(释放文件、关闭流)
}
关键字说明
try:监控异常代码块catch:捕获对应类型异常,处理错误finally:资源释放专用(文件流、数据库连接)throw:主动抛出异常,中断程序运行
六、五种本地存储方案对比
| 方案 | 优点 | 缺点 | 使用场景 |
|---|---|---|---|
| JSON | 结构清晰、支持复杂对象、易序列化 | 原生无 API,需 Newtonsoft | 列表、对象集合、表格数据 |
| INI | 轻量、读写速度快、配置专用 | 不支持嵌套对象,只存简单键值 | 软件参数、串口 / 相机 / 数据库配置 |
| CSV | Excel 可打开、纯文本、无第三方依赖 | 复杂文本解析错乱,无嵌套 | 简单报表导出、一维列表 |
| Settings | VS 可视化配置、开箱即用、类型安全 | 存储路径固定,不适合多套配置 | 用户界面布局、简单全局参数 |
| XML | 原生.NET 支持,层级结构 | 文件体积大、语法繁琐 | 老旧项目配置,现已被 JSON 替代 |
七、总结
- 简单键值配置优先使用 INI、Settings,开发效率最高;
- 列表、复杂对象展示存储优先 JSON+DataGridView;
- 需要 Excel 打开导出数据选择 CSV;
- 所有文件 IO、类型转换、数组操作代码必须包裹
try-catch防止程序崩溃; - INI 底层依赖 Windows 非托管 kernel32 API,跨平台程序不建议使用;
- 资源操作(FileStream、StreamReader)统一使用
using自动释放资源,避免文件占用。