当前位置: 首页 > news >正文

Rust:如何访问 *.ini 配置文件?

在 Rust 中读写 INI 文件,推荐使用成熟的 configparserini 库。下面提供两种实现方案(基础和高阶),包含完整代码示例:


方案一:使用 configparser(功能更强大)

1. 添加依赖
[dependencies]
configparser = "3.0.2"
anyhow = "1.0"  # 可选,用于错误处理
2. 读写 INI 文件完整示例
use anyhow::Result;
use configparser::ini::Ini;fn main() -> Result<()> {// ===== 写入 INI 文件 =====let mut config = Ini::new();// 添加全局值config.set("", "debug", Some("true"));config.set("", "timeout", Some("30"));// 添加带节的配置config.set("server", "host", Some("localhost"));config.set("server", "port", Some("8080"));// 添加另一个节config.set("user", "name", Some("Alice"));config.set("user", "active", Some("yes"));// 写入文件(支持注释)config.write_to_path("config.ini")?;// ===== 读取 INI 文件 =====let mut config_read = Ini::new();config_read.load("config.ini")?;// 读取全局值let debug = config_read.getbool("", "debug")?.unwrap();println!("Debug enabled: {}", debug);// 读取带节的值let port: i32 = config_read.get("server", "port")?.parse().unwrap_or(8080);println!("Server port: {}", port);// 读取整段if let Some(user_section) = config_read.sections().get("user") {println!("User name: {}", user_section["name"]);}// 更新并保存config_read.set("user", "active", Some("no"));config_read.write_to_path("config.ini")?;Ok(())
}
3. 高级特性
// 1. 自定义解析类型
let timeout: u64 = config_read.getuint("", "timeout")?.unwrap();// 2. 添加注释
config.set_comment("", "debug", vec!["; Global debug flag"]);
config.set_section_comment("user", vec!["", "# User settings", ""]);// 3. 多行值处理
config.set("multiline", "description", Some("这是\\n多行\\n值"));
let desc = config.get("multiline", "description").unwrap();
// => "这是\n多行\n值"// 4. 错误处理强化
match config.get("invalid_section", "key") {Ok(Some(val)) => println!("Value: {}", val),Ok(None) => println!("Key not found"),Err(e) => eprintln!("Error: {}", e),
}

方案二:使用 ini(轻量级)

1. 添加依赖
[dependencies]
ini = "3.0.1"
2. 基础读写操作
use ini::Ini;
use anyhow::Result;fn main() -> Result<()> {// ===== 创建新INI文件 =====let mut conf = Ini::new();// 添加全局属性conf.with_general_section().set("debug", "true").set("timeout", "30");// 添加节conf.with_section(Some("server")).set("host", "localhost").set("port", "8080");// 添加带注释的节conf.with_section(Some("user")).set("name", "Alice").set("active", "yes");// 写入文件conf.write_to_file("config.ini")?;// ===== 读取文件 =====let conf_read = Ini::load_from_file("config.ini")?;// 读取全局属性if let Some(debug_val) = conf_read.general_section().get("debug") {println!("Debug: {}", debug_val);}// 读取具体节if let Some(user) = conf_read.section(Some("user")) {let name = user.get("name").unwrap_or_default();println!("User name: {}", name);}// 遍历所有节for (sec, props) in &conf_read {println!("[{sec}]");for (key, value) in props.iter() {println!("{key} = {value}");}}Ok(())
}
3. 自定义配置
// 1. 自定义分隔符(默认为 =)
let mut conf = Ini::new_custom();
conf.section_mut(Some("section")).insert_with_separator("key", "value", ":");
// => key: value// 2. 保留注释
let conf = Ini::load_from_file("config.ini")?;
println!("原始注释: {:#?}", conf);// 3. 复杂数据类型
conf.with_section(Some("database")).set("port", 5432.to_string()).set("active", true.to_string());

功能对比表

特性configparserini
类型转换✅ (getint, getbool 等)
注释处理✅ (完整支持)✅ (部分支持)
多行值
默认值支持
文件自动重载
错误处理⭐⭐⭐⭐⭐⭐
性能⭐⭐⭐⭐⭐⭐⭐
文件大小限制

错误处理最佳实践

use configparser::ini::IniError;fn load_config() -> Result<(), IniError> {let mut config = Ini::new();// 优雅处理缺失值let host = config.get("server", "host").ok_or(IniError::MissingSectionOrKey("server.host".into()))?;// 强制类型转换let port: u16 = config.get("server", "port").and_then(|s| s.parse().ok()).ok_or(IniError::ValueError("Invalid port format".into()))?;println!("Connecting to {host}:{port}");Ok(())
}

INI 文件标准示例

; 全局配置
debug = true
timeout = 30[server]
# 服务器地址
host = 127.0.0.1
port = 8080  ; HTTP 端口[database]
user = dbadmin
password = "secret!@#$"

替代方案:手动解析(不推荐)

对于简单需求可自行处理:

use std::fs;
use anyhow::Context;fn parse_ini(path: &str) -> anyhow::Result<()> {let contents = fs::read_to_string(path)?;let mut current_section = "default";for line in contents.lines() {let line = line.trim();if line.is_empty() || line.starts_with(';') || line.starts_with('#') {continue;}if let Some(section) = line.strip_prefix('[').and_then(|s| s.strip_suffix(']')) {current_section = section;continue;}if let Some((key, value)) = line.split_once('=') {let key = key.trim();let value = value.trim();println!("Section: {current_section}, Key: {key}, Value: {value}");}}Ok(())
}

注意:手动解析无法处理复杂情况(如转义字符、多行值等),建议优先使用现成库。

根据需求选择库:

  • 需要复杂值类型转换 → 选 configparser
  • 只需要基本键值读取 → 选 ini
  • 需要集成系统配置 → 考虑 confy (基于 serde)
http://www.xdnf.cn/news/1235593.html

相关文章:

  • 关于车位引导及汽车乘梯解决方案的专业性、系统性、可落地性强的综合设计方案与技术实现说明,旨在为现代智慧停车楼提供高效、安全、智能的停车体验。
  • Noob靶场练习
  • 【python实用小脚本-169】『Python』所见即所得 Markdown 编辑器:写完即出网页预览——告别“写完→保存→刷新”三连
  • Rustdesk中继服务器搭建(windows 服务器)
  • SQL注入SQLi-LABS 靶场less31-38详细通关攻略
  • Python篇--- Python 的加载、缓存、覆盖机制
  • (FD Conv)Frequency Dynamic Convolution for Dense Image Prediction论文精读(逐段解析)
  • vscode的Remote-SSH插件配置SSH主机方法
  • 构造类型--结构体,共同体联合体,枚举
  • 知识蒸馏 - 基于KL散度的知识蒸馏 HelloWorld 示例 采用PyTorch 内置函数F.kl_div的实现方式
  • 标记-清除算法中的可达性判定与Chrome DevTools内存分析实践
  • Rust: 获取 MAC 地址方法大全
  • webrtv弱网-QualityScalerResource 源码分析及算法原理
  • 集成电路学习:什么是USB HID人机接口设备
  • Hertzbeat如何配置redis?保存在redis的数据是可读数据
  • PostgreSQL面试题及详细答案120道(21-40)
  • 腾讯人脸识别
  • 14.Redis 哨兵 Sentinel
  • C++中多线程和互斥锁的基本使用
  • [硬件电路-148]:数字电路 - 什么是CMOS电平、TTL电平?还有哪些其他电平标准?发展历史?
  • 本地环境vue与springboot联调
  • 2025年6月电子学会青少年软件编程(C语言)等级考试试卷(四级)
  • [硬件电路-143]:模拟电路 - 开关电源与线性稳压电源的详细比较
  • Ubuntu22.4部署大模型前置安装
  • webrtc弱网-QualityScaler 源码分析与算法原理
  • ubuntu apt安装与dpkg安装相互之间的关系
  • (一)全栈(react配置/https支持/useState多组件传递/表单提交/React Query/axois封装/Router)
  • 自动驾驶中的传感器技术18——Camera(9)
  • GitLab 代码管理平台部署及使用
  • Java基本技术讲解