【Rust每周一库】csv – 文件读写库
- 2020 年 2 月 20 日
- 筆記
这次搬运的库是很多数据分析师、数据科学家、以及金融分析师常用的csv文件库。
csv
用Rust实现的一个高性能、灵活的CSV读写器,支持Serde.
官方文档:
https://docs.rs/csv
使用方法:
将以下配置加进你的 Cargo.toml
:
[dependencies] csv = "1.1"
例子:
简单示范如何从stdin读取CSV数据并通过stdout将每一条记录打印出来。
use std::error::Error; use std::io; use std::process; fn example() -> Result<(), Box<dyn Error>> { // 建立 CSV 读取器并且遍历每一条记录。 let mut rdr = csv::Reader::from_reader(io::stdin()); for result in rdr.records() { // 遍历器会返回Result<StringRecord, Error>,所以我们在这里检查是否有错误。 let record = result?; println!("{:?}", record); } Ok(()) } fn main() { if let Err(err) = example() { println!("error running example: {}", err); process::exit(1); } }
以上的例子可以用以下命令运行:
$ git clone git://github.com/BurntSushi/rust-csv $ cd rust-csv $ cargo run --example cookbook-read-basic < examples/data/smallpop.csv
与 Serde一起使用时:
示范如何从stdin读取CSV数据并且将数据映射到定制结构体。结构体中的成员名称会默认与CSV数据中的表头相对应。
use std::error::Error; use std::io; use std::process; use serde::Deserialize; #[derive(Debug, Deserialize)] struct Record { city: String, region: String, country: String, population: Option<u64>, } fn example() -> Result<(), Box<dyn Error>> { let mut rdr = csv::Reader::from_reader(io::stdin()); for result in rdr.deserialize() { // 这里需要注意,我们需要为自动反序列化提供一个类型提示 let record: Record = result?; println!("{:?}", record); } Ok(()) } fn main() { if let Err(err) = example() { println!("error running example: {}", err); process::exit(1); } }
以上的例子可以用以下命令运行:
$ git clone git://github.com/BurntSushi/rust-csv $ cd rust-csv $ cargo run --example cookbook-read-serde < examples/data/smallpop.csv
下面的例子演示了如何将数据以CSV数据形式写入stdout:
extern crate csv; use std::error::Error; use std::io; use std::process; fn example() -> Result<(), Box<Error>> { let mut wtr = csv::Writer::from_writer(io::stdout()); // 当不与Serde共同使用时,表头可以按照与其他记录同样的方式写入 wtr.write_record(&["city", "region", "country", "population"])?; wtr.write_record(&["Southborough", "MA", "United States", "9686"])?; wtr.write_record(&["Northbridge", "MA", "United States", "14061"])?; wtr.flush()?; Ok(()) } fn main() { if let Err(err) = example() { println!("error running example: {}", err); process::exit(1); } }
以上的例子可以用以下命令运行:
$ git clone git://github.com/BurntSushi/rust-csv $ cd rust-csv $ cargo run --example cookbook-write-basic > /tmp/simplepop.csv
与Serde一起使用时:
extern crate csv; #[macro_use] extern crate serde_derive; use std::error::Error; use std::io; use std::process; #[derive(Debug, Serialize)] struct Record { city: String, region: String, country: String, population: Option<u64>, } fn example() -> Result<(), Box<Error>> { let mut wtr = csv::Writer::from_writer(io::stdout()); // 当用结构体通过Serde写入记录时,表头会被自动写入 wtr.serialize(Record { city: "Southborough".to_string(), region: "MA".to_string(), country: "United States".to_string(), population: Some(9686), })?; wtr.serialize(Record { city: "Northbridge".to_string(), region: "MA".to_string(), country: "United States".to_string(), population: Some(14061), })?; wtr.flush()?; Ok(()) } fn main() { if let Err(err) = example() { println!("error running example: {}", err); process::exit(1); } }
以上的例子可以用以下命令运行:
$ git clone git://github.com/BurntSushi/rust-csv $ cd rust-csv $ cargo run --example cookbook-write-serde > /tmp/simplepop.csv
例子:用过滤器搜索
extern crate csv; use std::env; use std::error::Error; use std::io; use std::process; fn run() -> Result<(), Box<Error>> { // 通过位置参数拿到查询语句 let query = match env::args().nth(1) { None => return Err(From::from("expected 1 argument, but got none")), Some(query) => query, }; // 通过stdin建立CSV读取器 // 通过stdout建立CSV写入器 let mut rdr = csv::Reader::from_reader(io::stdin()); let mut wtr = csv::Writer::from_writer(io::stdout()); // 在读取数据记录之前,先写入表头记录 wtr.write_record(rdr.headers()?)?; // 通过rdr遍历所有记录,然后通过wre写入只含有“query”的记录 for result in rdr.records() { let record = result?; if record.iter().any(|field| field == &query) { wtr.write_record(&record)?; } } // CSV写入器使用内部缓冲器,要记得完成后刷新清空。 wtr.flush()?; Ok(()) } fn main() { if let Err(err) = run() { println!("{}", err); process::exit(1); } }
在编译之后,运行这段代码时加入 MA
作为查询语句,可以看到结果中只有一条记录复合查询条件:
$ cargo build $ ./csvtutor MA < uspop.csv City,State,Population,Latitude,Longitude Reading,MA,23441,42.5255556,-71.0958333
本文来源于 cookbook.