26.Winfrom —— ini,csv,setting数据读写,try.cath

目录

[一、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 表格展示

功能说明

  1. Newtonsoft.Json 反序列化本地 json 文本
  2. 自定义 DataGridView 列(地址文本、图片、alt 提示)
  3. 本地路径加载图片绑定表格 Image 列
  4. 单元格点击调用系统浏览器打开链接

完整代码

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; }
    }
}

核心知识点

  1. DataPropertyName:绑定实体类属性名,实现数据源自动映射单元格
  2. DataGridViewImageColumn.ImageLayout.Zoom:图片等比缩放适配单元格
  3. Process.Start(url):调用系统默认浏览器打开网址
  4. Newtonsoft.Json:第三方高性能 JSON 序列化库,需 NuGet 安装
  5. 实体分离:img_url存文件路径(持久化),proImage内存图片(仅界面展示)

二、INI 配置文件读写(案例 2)

两种封装方案

  1. 简易INITool:极简封装,依赖 AppConfig 读取 ini 文件路径
  2. 完整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 格式规则

  1. 第一行为表头,逗号分隔字段
  2. 每行一条数据,字段逗号隔开
  3. 缺陷:字段内容包含逗号 / 换行时会解析错乱,复杂表格推荐 JSON

示例文件内容:

cs 复制代码
姓名,年龄,性别
梅西,20,男
张三,25,女

四、项目 Settings 用户配置(案例 4)

特点

  1. VS 可视化配置,无需手动写 xml
  2. Application程序级(只读)、User用户级(可运行修改保存)
  3. 自动序列化,支持 string、int、bool、Color 等类型
  4. 存储路径:C:\Users\ 当前用户 \AppData\Local\ 项目名

使用步骤

  1. 项目右键 → 属性 → 设置 → 添加 name/age/sex 字段
  2. 代码读写
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)

核心作用

捕获程序运行错误,避免程序直接崩溃,友好提示错误信息。

分层捕获规则(优先级从上到下)

  1. 特定细分异常(精准捕获)
    • FormatException:字符串转数字格式错误
    • OverflowException:数值超出类型范围
    • IndexOutOfRangeException:数组索引越界
    • NullReferenceException:空对象调用属性 / 方法
    • DivideByZeroException:除以 0
    • ArgumentException:传入非法参数
  2. 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 替代

七、总结

  1. 简单键值配置优先使用 INI、Settings,开发效率最高;
  2. 列表、复杂对象展示存储优先 JSON+DataGridView;
  3. 需要 Excel 打开导出数据选择 CSV;
  4. 所有文件 IO、类型转换、数组操作代码必须包裹try-catch防止程序崩溃;
  5. INI 底层依赖 Windows 非托管 kernel32 API,跨平台程序不建议使用;
  6. 资源操作(FileStream、StreamReader)统一使用using自动释放资源,避免文件占用。