【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.