CSV 文件操作
安装csv 文件cartes包
cargo add csv
或者修改Cargo.toml配置:
csv = "1.3.1"
样例代码:
#![allow(unused)] fn main() { use std::{error::Error, io, process}; use anyhow::Result; use csv::Reader; use csv::{ReaderBuilder, WriterBuilder}; use serde::{Deserialize, Serialize}; /// 定义 CSV 结构体 并使用 serde 进行序列化和反序列化 /// 使用 serde 的属性来指定字段名和映射 #[derive(Debug, Deserialize, Serialize)] struct Employee { #[serde(rename = "ID")] id: u32, #[serde(rename = "Name")] name: String, #[serde(rename = "Age")] age: u8, #[serde(rename = "Department")] department: String, #[serde(rename = "Salary")] salary: f64, } /// 使用 serde 的属性来指定字段名和映射 #[derive(Debug, serde::Deserialize)] struct Record { city: String, region: String, country: String, population: Option<u64>, } /// 处理 CSV 文件 fn process_employees(input_path: &str, output_path: &str) -> Result<()> { // 读取 CSV 文件 (自动推断分隔符) let mut reader = ReaderBuilder::new() .has_headers(true) .from_path(input_path)?; // 反序列化为 Employee 结构体 let employees: Vec<Employee> = reader.deserialize().collect::<Result<_, _>>()?; // 收集时处理错误 // 过滤数据: 保留薪资 > 5000 且年龄 < 50 的员工 let filtered: Vec<_> = employees .into_iter() .filter(|e| e.salary > 5000.0 && e.age < 50) .collect(); // 写入新 CSV let mut writer = WriterBuilder::new() .delimiter(b',') .has_headers(false) .from_path(output_path)?; // 写入表头 writer.write_record(&["ID", "Name", "Age", "Department", "Salary"])?; // 序列化并写入数据 for employee in filtered { //序列化并写入数据 writer.serialize(employee)?; } writer.flush()?; // 确保数据写入磁盘 Ok(()) } /// 处理大型 CSV 文件 fn process_large_csv() -> Result<()> { // 读取 CSV 文件 let mut reader = Reader::from_path("data/large_data.csv")?; // 逐行读取并处理 // 使用迭代器逐行读取 for result in reader.deserialize::<Employee>() { let employee: Employee = result?; // 逐条处理避免内存溢出 println!("{}", employee.name) } Ok(()) } /// 读取 CSV 文件并处理数据 fn csv_sample() -> Result<()> { // 输入输出文件路径 let input = "data/employees.csv"; let output = "data/filtered_employees.csv"; // 处理数据 process_employees(input, output)?; println!("CSV 处理完成!结果已保存至 {}", output); Ok(()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_csv_sample() { assert!(csv_sample().is_ok()); } #[test] fn test_process_large_csv() { assert!(process_large_csv().is_ok()); } } }