Transfert content of a file


#1

Hello,

I’m trying to transfert the content of a file in another file (created by the application)

fn openfile(file: String, name: &str) -> Result<File, io::Error> {
    let mut f = File::open(file)?;
    let mut e = File::open(name)?;
    let mut s = String::new();
    
    f.read_to_string(&mut s)?;
    println!("{}\n\n", s);
    match e.write_all(&mut s.as_bytes()) {
        Err(why) => {
            panic!("couldn't write to {}: {}", name, why.description())
        },
        Ok(_) => println!("successfully wrote to {}", name),
    }

    Ok(f)
}

The println print correctly the content of a file but the write_all function panic.
“other os error”.

How can I do what I want to do ?
Another question (while i’m here), did I use the question mark operator correcty ?

Thanks for the help :slight_smile:


#2

open is for reading only. You probably want create for the file you’re writing to.


#3

Instead of doing the read followed by the write, you could use std::io::copy : https://doc.rust-lang.org/nightly/std/io/fn.copy.html


#4

@kornel
omg i’m a dumb, I was doing it like in C.
Thanks for the information


#5

If all you’re doing is copying a file, you should actually use std::fs::copy because it copies a lot more than just the contents, including permissions and NTFS file streams. Also it can be significantly faster (in particular on Windows).


#6

Two points that aren’t relevant when using the proper functions, but nevertheless:

  • for arbitary files, don’t read them into a string (it requires UTF-8), instead use read_to_end into a Vec
  • instead of using why.description() format just why which should give you a more detailed error message (Error::description(), because it has to return a string slice, is kind of a last resort for when you don’t want to call code that may allocate).