Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取CSV或压缩CSV,具体取决于文件名_Csv_Rust_Zip - Fatal编程技术网

读取CSV或压缩CSV,具体取决于文件名

读取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

乍一看,我有点被一个这么简单的问题困住了。我想写一个简单的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> {
    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"