Search code examples
rustfile-permissions

Cannot write to file opened with `File::open`


This program is ment to get a template (the content) of a file and apply it to all files in a directory that start with }B.

The following Code compiles in my IDE and the terminal (cargo run), with the error: Couldn't write file: Os { code: 5, kind: PermissionDenied, message: "access denied" } The Cargo run error

The Error shows up in the apply_template function in the file.write_all() line.

The Cargo.toml file:

[package]
name = "insert_text"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
regex = "1.7.2"

The main.rs file (only top section):

fn main() {
    let template = read_template();
    apply_template(&template);
}

fn get_user_input(what_input: &str) -> String{
    println!("Please enter the Path where {} is.", what_input);
    let mut user_input = String::new();
    io::stdin().read_line(&mut user_input).expect("Not a Valid Input");
    return user_input;
}

fn read_template() -> String{
    let user_input = get_user_input("template");
    let mut path = Path::new(&user_input);
    let mut file = match fs::File::open(path) {
        Ok(file) => file,
        Err(why) => { panic!("couldn't open: {}", why)}
    };
    let mut template_content = String::new();
    match file.read_to_string(&mut template_content){
        Ok(_) => println!("Successfully read template"),
        Err(why) => {println!("Couldn't convert file to template: {}", why)},
    }
    return template_content;

}

fn apply_template(template : &str) {
    //let mut user_input = get_user_input("Folder");
    let mut path_to_folder = Path::new("C:/Users/micrs/Documents/Neuer Ordner/");
    let files = fs::read_dir(path_to_folder).unwrap();

    let re = Regex::new(r"}B.*").unwrap();
    for file in files{
        if re.is_match(&file.as_ref().unwrap().file_name().to_str().unwrap()){
            let file_path = file.unwrap().path();

            let mut file = File::open(file_path).expect("Couldn't find file");
            file.write_all(template.as_bytes()).expect("Couldn't write file");


        }
    }
    println!("Successfully changed files.")

I aleready tried

  1. checking properties, it should be able to write to that file
  2. cargo run in the admin console (still same error)

How I can get the program to write to those files.


Solution

  • In the documentation of File::open you'll see that it tries to open the file in read-only mode. This does not allow you to write to your file which you are attempting here:

    let mut file = File::open(file_path).expect("Couldn't find file");
    file.write_all(template.as_bytes()).expect("Couldn't write file");
    

    Use File::create, which opens the file in write-only mode, instead:

    let mut file = File::create(file_path).expect("Couldn't find file");
    file.write_all(template.as_bytes()).expect("Couldn't write file");