Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy file with tokio::fs

I am trying to copy a file using tokio for async operations. I saw that tokio doesn't expose any method like tokio::fs::copy which would do the job for me (like the equivalent std::fs::copy for sync operations).

While trying to implement such a method, i can't actually create a file using tokio::fs::File::create, that is the following code doesn't create any file:

tokio::fs::File::open("src.txt")
    .and_then(|mut file| {
        let mut content = Vec::new();
        file.read_buf(&mut content)
            .map(move |_| tokio::fs::File::create("dest.txt"))
    })
    .map_err(Error::from)
    .map(drop);

How can I copy src.txt into dest.txt using tokio and async fs methods?

Here is a link to Playground

like image 886
Nick Avatar asked Sep 06 '25 16:09

Nick


1 Answers

Now tokio::fs has it's own copy implementation in version Tokio 0.2.11. (reference)

//tokio = {version = "0.2.11", features = ["full"] }
#[tokio::main]
async fn main()-> Result<(), ::std::io::Error>{
    tokio::fs::copy("source.txt","target.txt").await?;

    Ok(())
}

Implementation is basically async-await version of the code below, please see the source code

Without async await ( Tokio 0.1.x )

You can use Copy future from tokio::io, which copies all bytes from input stream to output stream.

//tokio-0.1.22
tokio::fs::File::open("src.txt")
    .and_then(|mut file_in| {
        tokio::fs::File::create("dest.txt")
            .and_then(move |file_out| tokio::io::copy(file_in, file_out))
    })
    .map_err(Error::from)
    .map(drop);

Playground


Your code is not working because read_buf returns Poll not the Future so it won't combine with the inner one. It will do the same work for the small sized file if you spawn Future which is created by tokio::fs::File::create (full code).

But be careful from the reference of read_buf :

Pull some bytes from this source into the specified BufMut

It doesn't read until the end of file with a single call. I don't know why this read example has no warning, it just says Read the contents of a file into a buffer, it looks like a misleading example.

like image 105
Ömer Erden Avatar answered Sep 09 '25 06:09

Ömer Erden