Failed to load file: Os { code: 5, kind: PermissionDenied, message: "Access is denied."

i am learning rust right now, and wanted to try and json file opener. i saw that i can use std::fs::File in order to read and write to files. so i made a file_manager and also used a small file for input outout i made (just to make input a little easier). here is the code:

main.rs

mod easy_io;
// easy_io is just a wrapper for std::stdin().read_line()
mod file_manager;
use std::{fs::File, io::Read};

fn main() {
    let file_name: String = easy_io::input("please select a file");
    let file_name: &str = file_name.trim();
    let mut users_file: File = file_manager::load_file(&file_name);
    let mut users: String = String::new();
    users_file.read_to_string(&mut users).expect("failed to load file");
    println!("{}", users);
}

and here is file_manager.rs:

use std::fs::File;
use std::path::Path;

pub fn load_file(name: &str) -> File{
    println!("{}", Path::new(name).exists());
    let file_created: File = if Path::new(name).exists() {File::open(name).expect("failed to read file")} else {File::create(name).expect("failed to create file")};
    return file_created;
}

how does rust have no issue creating/loading the file, but fails to find it when trying to read it?

File::create opens files in write-only mode.

You could instead

        } else {
            File::options()
                .read(true)
                .write(true)
                .create_new(true)
                .open(name)
                .expect("failed to create file")
        }

Or even

    pub fn load_file(name: &str) -> File {
        File::options()
            .read(true)
            .write(true)
            .create(true)
            .open(name)
            .unwrap()
    }

You need the write in either case as that's required when creating a new file.

See OpenOptions for more details.

I would prefer the latter as the if/else is a TOCTOU situation anyway.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.