Home > database >  rust reading lines amount file and iterating over them
rust reading lines amount file and iterating over them

Time:12-04

I am attempting to write a program that shortens a file to n lines.

I have difficulties regarding reading the lines of the file, and then enumerating over them after. Expectedly the iterator does not work if count() is called on it and then iterated with due to the nature of count() count(): Consumes the iterator, counting the number of iterations and returning it.

However, creating two separate buffers from the file produces similar results?

    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() {
        ...
    }

Opening two files and create a buffer from each seems to produce the same results.

Why does this happen, and how do I read the amount of lines of a file as well as iterating over it?

CodePudding user response:

You have to seek to the beginning in between uses of a File or you'll continue reading where the last read left off. It is a little hidden here because the Read on &File uses interior mutability and is equivalent to the one on File.

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() {
    ...
}
  • Related