X-CSV-Reader:一个使用Rust实现CSV命令行读取器

🎈效果演示

csv

⚡️快速上手

  • 依赖导入:
cargo add csv
  • 读取实现:
use std::error::Error;
use std::fs::File;
use std::path::Path;fn read_csv<P: AsRef<Path>>(filename: P) -> Result<(), Box<dyn Error>> {let file = File::open(filename)?;let mut rdr = csv::Reader::from_reader(file);for result in rdr.records() {let record = result?;println!("{:?}", record);}Ok(())
}fn main() -> Result<(), Box<dyn Error>> {let filename = "src/email.csv";read_csv(filename)
}

这是一段简单的Rust程序,演示了如何使用csv``crate中的读取API,通过指定csv路径进行csv数据的读取。

  1. use std::error::Error;, use std::fs::File;, use std::path::Path;

    • 这些是Rust语言中用于导入标准库中的错误处理、文件操作和路径相关模块的语句。
  2. fn read_csv<P: AsRef<Path>>(filename: P) -> Result<(), Box<dyn Error>>

    • 这是一个函数定义,名为read_csv,它接受一个实现了AsRef<Path> trait 的泛型参数P,表示文件名。函数返回一个Result枚举类型,其中Ok(())表示成功,Err包含一个实现了Error trait 的错误对象的Box指针。
    • 函数打开指定的CSV文件,创建一个CSV读取器(csv::Reader),然后遍历文件中的每一行记录并打印出来。
  3. fn main() -> Result<(), Box<dyn Error>>

    • 这是程序的入口点,也是主函数。它也返回一个Result枚举类型,用于处理可能出现的错误。
    • main函数中,指定了要读取的CSV文件的文件名为"src/email.csv",然后调用read_csv函数来处理这个文件。
  4. let file = File::open(filename)?;

    • read_csv函数中,这行代码尝试打开指定的文件,?操作符用于处理可能出现的错误,如果出现错误,则会将错误传播到调用方。
  5. let mut rdr = csv::Reader::from_reader(file);

    • 创建一个CSV读取器rdr,并从打开的文件中读取数据。
  6. for result in rdr.records() { ... }

    • 使用for循环遍历CSV文件中的每一行记录。
  7. let record = result?;

    • 在循环中,尝试将每一行记录解析为csv::StringRecord类型的record?操作符用于处理可能的解析错误。
  8. println!("{:?}", record);

    • 打印每一行记录的内容。
  9. Ok(())

    • 在函数末尾,返回一个Ok(())表示函数执行成功。

  • 读取结果:

image-20240526192615414

csv文件的读取功能基本实现了,但是每次读取需要我们手动修改代码,指定要读取的csv文件路径,相对还是不够实用和灵活,特别是对于非程序猿来说。下面将对代码进行进一步提取和优化,将读取的功能封装为命令行程序,提升使用体验。


💥命令行程序封装

关于命令行,Rustcrate中有很多不错的库,在之前我的文章中也提及了部分,这里选择使用clap这个crate来实现。

[dependencies]
ansi_term = "0.12.1"
clap = { version = "4.5.4", features = ["derive"] }
csv = "1.3.0"
prettytable-rs = "0.10.0"
  • 结构分离,为了利于维护,将读取CSV文件的方法独立在lib.rs中,命令行参数处理等内容依旧在main.rs

  • lib.rs

pub fn read_csv<P: AsRef<Path>>(filename: P) -> Result<(), Box<dyn Error>> {let file = File::open(filename)?;let mut rdr = csv::Reader::from_reader(file);let mut table = Table::new();// 添加表头let headers = rdr.headers()?.iter().map(|h| Cell::new(h).style_spec("Fg=green")).collect();table.add_row(Row::new(headers));// 添加记录for result in rdr.records() {let record = result?;let cells: Vec<Cell> = record.iter().map(|field| Cell::new(field)).collect();table.add_row(Row::new(cells));}table.printstd();Ok(())
}

感觉没啥新的东西可以讲的,这个方法的主要逻辑在上面已经说过,至于内容的打印,还是使用之前在X-SCAN端口扫描器中使用的Table进行美化。

  • main.rs
use x_csvreader::read_csv;
#[derive(Parser, Debug)]
struct Args {#[clap(short, long, help = "The path to the CSV file.")]path: String,
}
fn print_infos() {println!("{}",Blue.paint(r#"__   __      _____  _______      __     _____                _\ \ / /     / ____|/ ____\ \    / /    |  __ \              | |\ V /_____| |    | (___  \ \  / /_____| |__) |___  __ _  __| | ___ _ __> <______| |     \___ \  \ \/ /______|  _  // _ \/ _` |/ _` |/ _ \ '__|/ . \     | |____ ____) |  \  /       | | \ \  __/ (_| | (_| |  __/ |/_/ \_\     \_____|_____/    \/        |_|  \_\___|\__,_|\__,_|\___|_|author:代号0408version:0.1.0"#));
}
fn main() {print_infos();let args = Args::parse();// 调用lib.rs中定义的read_csv函数match read_csv(&args.path) {Ok(_) => {println!("=============================");println!("CSV 文件读取成功!");}Err(e) => {eprintln!("读取 CSV 文件时出现错误:{}", e);}}
}

逻辑简单,就不赘述了。如果不了解字符打印美化和表格美化这两个lib基本使用的,建议翻下我往期的文章,都是有写的。

那么如何使用呢?

cargo run -- --path <csv文件路径>

不妨将开头的效果复现一下:

cargo run -- --path C:\RustProjects\x-csvreader\src\email.csv

当然,为了演示的效果,这里选择的CSV文件数据量并不大,处理大数据量的文件也是可以的,只不过打印出来的表格数据可能会出现终端 霸屏的情况,纸上得来终觉浅!建议你自己试试,这里就不截图了。


📃总结

这篇文章主要学习如何基于Rust使用csv这个crate构建一个CSV文件读取器的过程。学习了csv相关的用法以及一些往期学过的crate的复习,兼顾了实用性和Rust的学习,是个很不错的练手小项目。


🔖相关资源

  • clap

  • csv

  • [CSV示例文件下载地址1](可供下载的 CSV 文件 |新西兰统计局 — CSV files for download | Stats NZ)

  • [CSV示例文件下载地址2](CSV File Examples – Staffbase Support Portal)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/16400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java面试】二、Redis篇(中)

文章目录 1、Redis持久化1.1 RDB1.2 AOF1.3 RDB与AOF的对比 2、数据过期策略&#xff08;删除策略&#xff09;2.1 惰性删除2.2 定期删除 3、数据淘汰策略4、主从复制4.1 主从全量同步4.2 增量同步 5、哨兵模式5.1 服务状态监控5.2 哨兵选主规则5.3 哨兵模式下&#xff0c;Redi…

商标注册申请名称的概率,多想名称选通过率好的!

近日给深圳客户申请的商标初审下来了&#xff0c;两个类别都下的初审&#xff0c;和当初的判断基本一致&#xff0c;普推知产老杨当时沟通说需要做担保申请注册也可以&#xff0c;后面选择了管家注册&#xff0c;最近大量的帮客户检索商标名称&#xff0c;分享下经验。 两个字基…

【PB案例学习笔记】-09滚动条使用

写在前面 这是PB案例学习笔记系列文章的第8篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gitee…

新书推荐:7.1 do while语句

本节必须掌握的知识点&#xff1a; 示例二十二 代码分析 汇编解析 ■do while语句其语法形式&#xff1a; do{ 语句块; }while(表达式) ■语法解析&#xff1a; ●执行do循环体内的语句块&#xff1b; ●判断while语句里的表达式&#xff0c;表达式为真继续下次循环&#…

stm32学习-串口收发(HEX/文本)数据包

串口收发HEX数据包 接线 TXDPA10RXDPA9按键PB1 配置流程 定义为固定包长&#xff0c;含包头包尾&#xff08;其中包头为0xFF&#xff0c;载荷数据固定为4字节&#xff0c;包围为0xFE&#xff09; 注意&#xff1a;固定包长/可变包长&#xff0c;或者包头包围是什么&#xf…

UI控件与视图层次:探索界面的无限可能

[OC]UI学习笔记 文章目录 [OC]UI学习笔记视图和视图层次结构CGRectUILabelUIButtonUIView控件UIView的层级关系UIWindow定时器和视图移动UISwitch进度条和滑动条控件步进器和分栏控件警告对话框与等待指示器UITextField 视图和视图层次结构 Objective-C中的UI编程主要围绕视图…

C++的哈希 哈希表 哈希桶

目录 Unordered系列关联式容器 什么是哈希 哈希表 闭散列 载荷因子α 扩容 查找 删除 字符串哈希算法 最终代码 开散列 插入 查找 删除 最终代码 完整代码 Unordered系列关联式容器 C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0…

大学校园广播“录编播”与IP广播系统技术方案

一、项目概述 1、校园IP网络广播系统概述 大学校园广播系统是学校整个弱电系统中的子系统&#xff0c;它是每个学校不可缺少的基础设施之一&#xff0c;在传递校园文化、传播校园新闻资讯方面发挥着重要的作用。近几年来&#xff0c;虽然视频技术和网络技术在飞速发展&#xf…

行为设计模式之策略模式

文章目录 概述原理结构图 代码实现小结 概述 策略模式(strategy pattern)的原始定义是&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。 在软件开发中也会遇到相似的情况&…

基于双差分值和RR间隔处理的心电信号R峰检测算法(MATLAB R2018A)

心电信号中的R峰是确定心率和节律、以及检测其它波形特征点&#xff08;图1A&#xff09;的基础。R峰的准确检测是心率变异性分析、心拍分割和心律失常识别重要的处理步骤。 现有的心电信号R峰检测方法主要为基于规则的决策法和基于深度学习的检测方法。基于规则的决策法通常对…

中国低调海外巨头,实力超乎想象!

在全球化的浪潮中&#xff0c;中国公司正以前所未有的速度和规模走向世界。他们或许低调&#xff0c;但却实力非凡&#xff0c;在国际市场上掀起了一股不可小觑的“中国风暴”。今天&#xff0c;就让我们揭开那些在国外牛逼到爆炸的中国公司的神秘面纱&#xff0c;深度解析他们…

mysql中InnoDB的表空间--系统表空间

大家好。上篇文章我们讲了InnoDB的独立表空间&#xff0c;我们知道了表空间被划分为许多连续的区&#xff0c;对于大小为16KB的页面来说&#xff0c;每个区默认由64个页组成&#xff0c;每256个区为一组&#xff0c;每个组最开始的几个页的类型是固定的。&#xff08;在这里强烈…

HCIP-Datacom-ARST自选题库__BGP判断【20道题】

1.传统的BGP-4只能管理IPV4单播路由信息&#xff0c;MP-BGP为了提供对多种网络层协议的支持&#xff0c;对BGP-4进行了扩展。其中MP-BGP对IPv6单播网络的支持特性称为BGP4&#xff0c;BGP4通过Next Hop属性携带路由下一跳地址信息。 2.BGP4通过Update报文中的Next Hop属性携带…

RK3568笔记二十六:音频应用

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 音频是我们最常用到的功能&#xff0c;音频也是 linux 和安卓的重点应用场合。 测试使用的是ATK-DLR3568板子&#xff0c;板载外挂RK809 CODEC芯片&#xff0c;RK官方驱动是写好的&#xff0c;不用在自己重新写。…

智慧城市运维可视化:透视未来城市高效管理的新视窗

行业痛点 现代城市运维是一个复杂而庞大的系统&#xff0c;涉及到诸多方面&#xff0c;包括交通、环境、能源等等。然而&#xff0c;在城市运维中&#xff0c;存在着一些现实的痛点&#xff0c;给城市管理者带来了不小的压力和困扰&#xff1a; 1、交通拥堵 随着城市化进程的…

帝国cms自定义专题列表模板list.var中获取对应专题下的信息、信息数量及信息所属栏目名称

帝国cms自定义专题列表模板list.var中获取对应专题下的信息、信息数量及信息所属栏目名称 代码如下&#xff1a; $rr $empire->fetch1("SELECT GROUP_CONCAT(id) from phome_enewsztinfo where ztid$r[id]"); $ff $rr[0]; $ga explode(",", $ff); …

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑分布式光伏高效消纳与负荷损失最小的区域配电网应急资源协同配置策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

一款网站源码下载开源工具 Website Downloader

一、简介 Website Downloader 是一款免费的网站源码下载器&#xff0c;下载任何网站的完整源代码&#xff0c;包括 JavaScript、样式表、图像等等&#xff0c;而且使用也非常简单&#xff0c;只需要粘贴网址&#xff0c;用户即可将网页链接内容下载到本地&#xff0c;而且自动…

堆(建堆算法,堆排序)

目录 一.什么是堆&#xff1f; 1.堆 2.堆的储存 二.堆结构的创建 1.头文件的声明&#xff1a; 2.向上调整 3.向下调整 4.源码&#xff1a; 三.建堆算法 1.向上建堆法 2.向下建堆法 四.堆排序 五.在文件中Top出最小的K个数 一.什么是堆&#xff1f; 1.堆 堆就…

Docker之xfs文件系统下安装报错解决方案

一、需求说明 centos系统下安装docker最新版的时候&#xff0c;安装成功&#xff0c;启动的时候报错。报错信息“failed to start daemon: error initializing graphdriver: overlay2: the backing xfs filesystem is formatted without d_type support, which leads to incorr…