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
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
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);
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.