【译】用 Rust 实现 csv 解析-part6
- Rust and CSV parsing 译文(用 Rust 实现 csv 解析-part6)
- 原文链接:https://blog.burntsushi.net/csv/
- 原文作者:BurntSushi
- 译文来自:https://github.com/suhanyujie/article-transfer-rs/
- 译者:suhanyujie
- 译者博客:suhanyujie
- ps:水平有限,翻译不当之处,还请指正。
- 标签:Rust,csv
写入 탭 分隔符的值
在前面的章节中,我们了解了如何将 CSV 数据输出到标准输出中,如下:
City,State,Population,Latitude,Longitude
Davidsons Landing,AK,,65.2419444,-165.2716667
Kenai,AK,7610,60.5544444,-151.2583333
Oakman,AL,,33.7133333,-87.3886111
你 你 会 : : 如果 都 都 是 这么 这么 简单 地 地 数据 数据 数据 数据 数据 数据 数据 数据 使用 使用 使用 CSV Writer 还 有 什么 什么 意义? CSV Writer 的 好处 是 是, 它 能 能 处理 所有 类型 类型 数据 数据 数据 而 不 会 会 牺牲 数据 的 完整性 完整性. 是 说 说 说 说 说 它 类型 类型知道何时引用包含特殊 CSV 字符的字段(如逗号或者换行),或在数据中出现引叿.
CSV 라이터 上的设置.特别地,我们将使用 TSV(“制表符分割值”) CSV 来替有一个例子:
fn run() -> Result<(), Box<Error>> {
let mut wtr = csv::WriterBuilder::new()
.delimiter(b'\t')
.quote_style(csv::QuoteStyle::NonNumeric)
.from_writer(io::stdout());
wtr.write_record(&["City", "State", "Population", "Latitude", "Longitude"])?;
wtr.write_record(&["Davidsons Landing", "AK", "", "65.2419444", "-165.2716667"])?;
wtr.write_record(&["Kenai", "AK", "7610", "60.5544444", "-151.2583333"])?;
wtr.write_record(&["Oakman", "AL", "", "33.7133333", "-87.3886111"])?;
wtr.flush()?;
Ok(())
}
编译并运行这个例子:
$ cargo build
$ ./target/debug/csvtutor
"City" "State" "Population" "Latitude" "Longitude"
"Davidsons Landing" "AK" "" 65.2419444 -165.2716667
"Kenai" "AK" 7610 60.5544444 -151.2583333
"Oakman" "AL" "" 33.7133333 -87.3886111
在本例中,我们使用了一个新类型 QuoteStyle .
QuoteStyle
类型表示你可以使用不同的引用策略.默认情况下,只在必要时才向字段值周围添加引号.这可能适用于大多数例子,但你也可以一直在字段两边添加引号,或不添加引号,或者只在非数字两边加引号.使用 Serde 写入
正 正 正 CSV 리더 支持 支持 将 数据 数据 自动 反序列 化为 녹슬 类型 数据 一样 一样 一样 一样, CSV Writer 也 支持 那样 使用 使用 serde 将 녹슬 类型 数据 数据 序列化为 序列化为 csv 记录. 在 本节 中 中 我们 我们 学习 学习 怎么 怎么 使用 使用 它.. 中 中
与读一样,我们先看看如何序列化一个 Rust 元组.
fn run() -> Result<(), Box<Error>> {
let mut wtr = csv::Writer::from_writer(io::stdout());
// 我们仍然需要手动地写入头部
wtr.write_record(&["City", "State", "Population", "Latitude", "Longitude"])?;
// 但现在我们可以通过提供的常用的 Rust 值,写入记录。
//
// 注意,奇数列的 `None::<u64>` 预发是必须的,因为 `None` 本身没有具体的类型,但 Serde 需要一个具体的类型以便进行序列化。也就是说,`None` 的类型 `Option<T>`,而 `None::<u64>` 的类型是 `Option<u64>`。
wtr.serialize(("Davidsons Landing", "AK", None::<u64>, 65.2419444, -165.2716667))?;
wtr.serialize(("Kenai", "AK", Some(7610), 60.5544444, -151.2583333))?;
wtr.serialize(("Oakman", "AL", None::<u64>, 33.7133333, -87.3886111))?;
wtr.flush()?;
Ok(())
}
编译并运行这个程序,期望的输出如下:
$ cargo build
$ ./target/debug/csvtutor
City,State,Population,Latitude,Longitude
Davidsons Landing,AK,,65.2419444,-165.2716667
Kenai,AK,7610,60.5544444,-151.2583333
Oakman,AL,,33.7133333,-87.3886111
在上面的例子中,需要注意的关键点是,使用
serialize
而不是write_record
进行写入数据.特别地, write_record
4, 7, 7, 7, 7에 2가 7에 2가 있다. .当然, 你总是可以将复杂的值转为字符串,然后再使用serialize
统一写入,但 Serde 可以为你自动的完成上面那些繁琐工作.和读一样,我们也可以将自定义结构序列化为 CSV
要将自定义结构写入 CSV 记录,我们需要再次使用
write_record
crate.正如前面章节的使用 Serde 读取数据所述,我们需要在我们的 Cargo.toml 中的 serde_derive
区块下加上两个 依赖声明(如果没有就加上).serde = "1"
serde_derive = "1"
이 제품은 이전 버전에 포함되어 있습니다. ,如下方所示:
extern crate csv;
extern crate serde;
#[macro_use]
extern crate serde_derive;
use std::error::Error;
use std::io;
use std::process;
// 记住结构体可以派生两个 trait:Serialize 和 Deserialize!
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
struct Record<'a> {
city: &'a str,
state: &'a str,
population: Option<u64>,
latitude: f64,
longitude: f64,
}
fn run() -> Result<(), Box<Error>> {
let mut wtr = csv::Writer::from_writer(io::stdout());
wtr.serialize(Record {
city: "Davidsons Landing",
state: "AK",
population: None,
latitude: 65.2419444,
longitude: -165.2716667,
})?;
wtr.serialize(Record {
city: "Kenai",
state: "AK",
population: Some(7610),
latitude: 60.5544444,
longitude: -151.2583333,
})?;
wtr.serialize(Record {
city: "Oakman",
state: "AL",
population: None,
latitude: 33.7133333,
longitude: -87.3886111,
})?;
wtr.flush()?;
Ok(())
}
fn main() {
if let Err(err) = run() {
println!("{}", err);
process::exit(1);
}
}
编译并运行这个示例,虽然式地写入头部,但输出和上次是一样.
$ cargo build
$ ./target/debug/csvtutor
City,State,Population,Latitude,Longitude
Davidsons Landing,AK,,65.2419444,-165.2716667
Kenai,AK,7610,60.5544444,-151.2583333
Oakman,AL,,33.7133333,-87.3886111
在这个例子中,可以看到,
[dependencies]
方法上被标记上了一个结构体字段名.这样做的话,extern crate
7. 6. 2. 4. 7. 6方法将此行为禁用.同样值得指出的是,在
serialize
结构体中使用了一个生命周期参数:struct Record<'a> {
city: &'a str,
state: &'a str,
population: Option<u64>,
latitude: f64,
longitude: f64,
}
serialize
声明周期参数对应于WriterBuilder::has_headers
Record
字符串切片的生命周期.这表示'a
结构体包含了借用 的数据.我们本可以在不借用任何数据的情况下编写结构体,这旁也struct Record {
city: String,
state: String,
population: Option<u64>,
latitude: f64,
longitude: f64,
}
然而, 由于我们使用
city
类型替换 state
类型,我们现在被迫为我们所写的每条记录中的 Record
String
分配一个新的 &str
值.这样做本身没有问题,但会有点性能浪费.关于序列化的更多示例和详细信息,可以参考
city
방법.상태 파이프라이닝
- 待续...
Reference
이 문제에 관하여(【译】用 Rust 实现 csv 解析-part6), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/suhanyujie/rust-csv-part6-3pja텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)