读取CSV或压缩CSV,具体取决于文件名
乍一看,我有点被一个这么简单的问题困住了。我想写一个简单的Rust程序,根据文件扩展名可以读取普通的CSV文件以及压缩的CSV文件,并输出这些文件的内容。当然,真正的问题有点不同,但我还没来得及开始解决实际问题就被卡住了-D 我尝试的是这样的:读取CSV或压缩CSV,具体取决于文件名,csv,rust,zip,Csv,Rust,Zip,乍一看,我有点被一个这么简单的问题困住了。我想写一个简单的Rust程序,根据文件扩展名可以读取普通的CSV文件以及压缩的CSV文件,并输出这些文件的内容。当然,真正的问题有点不同,但我还没来得及开始解决实际问题就被卡住了-D 我尝试的是这样的: use std::io::Error; use std::fs::File; use std::io; use csv::Reader; fn read_csv(filename: &str) -> Result<(), Error
use std::io::Error;
use std::fs::File;
use std::io;
use csv::Reader;
fn read_csv(filename: &str) -> Result<(), Error> {
let f = std::fs::File::open(filename)?;
// Want to return a reader object which either reads from ZipFile or from "normal" File
let mut rdr: Reader<Box<dyn io::Read>> =
if filename.ends_with("zip") { // zip case
let mut ar = zip::read::ZipArchive::new(f)?;
let zf = ar.by_index(0)?;
csv::ReaderBuilder::new().delimiter(b',').from_reader(Box::new(zf))
} else { // csv case
csv::ReaderBuilder::new().delimiter(b',').from_reader(Box::new(f))
};
// From here on, I don't want to care whether I'm reading from a zipped CSV or normal CSV
for rec in rdr.records() {
rec?.iter().for_each(|v| println!("{},", v));
}
Ok(())
}
fn main() -> Result<(), Error> {
let filename_csv = "tmp.csv";
let filename_zip = "tmp.csv.zip"; // same as tmp.csv but zipped
read_csv(filename_csv);
read_csv(filename_zip);
Ok(())
}
正如您所注意到的,一个变量在声明它的作用域的末尾被删除 幸运的是,您可以在另一个作用域中声明变量,并将其赋值,因此您可以编写如下内容:
使用std::io::Error;
使用std::fs::File;
使用std::io;
使用csv::Reader;
fn read_csv(文件名:&str)->结果{
让f=std::fs::File::open(文件名)?;
让mut-ar;
//要返回从ZipFile或“普通”文件读取的reader对象吗
让mut-rdr:Reader=
如果filename.u以(“zip”){//zip大小写结尾
ar=zip::read::ZipArchive::new(f)?;
设zf=ar.by_指数(0)?;
csv::ReaderBuilder::new()。分隔符(b',')。来自_reader(框::new(zf))
}else{//csv案例
csv::ReaderBuilder::new()。分隔符(b',')。来自_reader(框::new(f))
};
//从现在开始,我不想关心我是从压缩的CSV还是从普通的CSV读取
对于rdr.records()中的记录{
rec?.iter()。对于每个({},v));
}
好(())
}
fn main()->结果{
让filename_csv=“tmp.csv”;
让filename_zip=“tmp.csv.zip”;//与tmp.csv相同,但已压缩
读取\u csv(文件名\u csv);
读取\u csv(文件名\u zip);
好(())
}
它将移动到声明
ar
的位置,因此它将在read\u csv
的末尾被删除,而不是在if
块的末尾。这是。。。这么简单,这么聪明!谢谢问题与:,然而,我的问题不是我不知道如何将两种不同类型(但实现相同特性)的对象分配给变量,而是我在变量的生存期方面遇到了问题。
error[E0597]: `ar` does not live long enough
--> src/main.rs:13:22
|
10 | let mut rdr: Reader<Box<dyn io::Read>> =
| ------- borrow later stored here
...
13 | let zf = ar.by_index(0)?;
| ^^ borrowed value does not live long enough
14 | csv::ReaderBuilder::new().delimiter(b',').from_reader(Box::new(zf))
15 | } else { // csv case
| - `ar` dropped here while still borrowed
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0597`.
error: could not compile `zipped-csv-read`
[dependencies]
zip = "0.5"
csv = "1.1"