rust阅读文件中数量行并对其进行迭代

cclgggtu  于 2022-12-04  发布在  其他
关注(0)|答案(1)|浏览(101)

我正在尝试写一个程序,它可以将一个文件缩短为n行。
我在阅读文件的行,然后枚举它们之后遇到了困难。如果在迭代器上调用count(),然后由于count()count(): Consumes the iterator, counting the number of iterations and returning it的性质而使用迭代器进行迭代,那么预期迭代器将不工作。
但是,从文件创建两个单独的缓冲区会产生类似的结果?

let path = Path::new(&args[1]);

    let file_result = OpenOptions::new().read(true).open(path);

    let file = match file_result {
        Ok(file) => file,
        Err(error) => {
            panic!("failed to open file: {}", error.to_string());
        }
    };

    let lines_amount = BufReader::new(&file).lines().count();

    if lines_amount == 0 {
        panic!("The file has no lines");
    }

    println!("{}", lines_amount);

    // this will not iterate, no matter the amount of lines in the file
    for (i, line_result) in BufReader::new(&file).lines().enumerate() {
        ...
    }

打开两个文件并从每个文件创建一个缓冲区似乎会产生相同的结果。
为什么会发生这种情况?我如何读取文件的行数并对其进行迭代?

hc2pp10m

hc2pp10m1#

你必须在使用File的间隙将seek返回到开头,否则你将从上一个read停止的地方继续阅读。这里有点隐藏,因为&File上的Read使用了内部可变性,并且等价于File上的Read

let path = Path::new(&args[1]);

let file_result = OpenOptions::new().read(true).open(path);

let mut file = match file_result {
    Ok(file) => file,
    Err(error) => {
        panic!("failed to open file: {}", error.to_string());
    }
};

let lines_amount = BufReader::new(&file).lines().count();

if lines_amount == 0 {
    panic!("The file has no lines");
}

println!("{}", lines_amount);

// reset files position to start
file.seek( std::io::SeekFrom::Start(0));

for (i, line_result) in BufReader::new(&file).lines().enumerate() {
    ...
}

相关问题