filerustfile-writingfile-read

Reading file before writing causing issue


To reproduce the issue. Run the below code twice. First it will work fine. But when there is data to read from file it will cause issue while writing back.

I assume, when file is not empty reading is changing the state of File type causing issue while writing.

use std::{
    fs::OpenOptions,
    io::{Read, Write},
};

fn main() {
    let mut file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open("todo.txt")
        .unwrap();

    // Reading task before writing causing issue.
    let mut read_task = String::new();
    file.read_to_string(&mut read_task)
        .expect("Issue reading to string");

    let write_tasks = "1\n2\n3\n4\n";
    file.set_len(0).expect("Issue in setting len to zero");
    file.write(write_tasks.as_bytes()).expect("Issue writing to file");
}

Solution

  • As noted in set_len()'s documentation:

    The file’s cursor isn’t changed. In particular, if the cursor was at the end and the file is shrunk using this operation, the cursor will now be past the end.

    Since you read it all, the cursor was at the end. So it becomes past the end, and when you're writing to the file, it writes there.

    You need to rewind() the cursor:

    use std::io::Seek;
    
    file.set_len(0).expect("Issue in setting len to zero");
    file.rewind().expect("issue rewinding cursor");
    file.write(write_tasks.as_bytes()).expect("Issue writing to file");