rjc2013
December 18, 2021, 9:59am
1
I'm porting some synchronous code to tokio, and I'm not sure how to port writeln!
.
I have this:
fn main() -> std::io::Result<()> {
use std::{fs, io, io::Write};
let mut f = io::BufWriter::new(fs::File::create("hello.txt")?);
writeln!(f, "Hello world")?;
Ok(())
}
which works OK. In my tokio port, I have this:
#[tokio::main]
async fn main() -> tokio::io::Result<()> {
use tokio::{fs, io};
let mut f = io::BufWriter::new(fs::File::create("hello.txt").await?);
// WHAT GOES HERE? writeln!(f, "Hello world")?;
Ok(())
}
writeln!
doesn't work, since it expects the core::fmt::Write
trait, which tokio's BufWriter doesn't implement (I think that's the problem, anyway).
Any guidance much appreciated!
1 Like
alice
December 18, 2021, 10:00am
2
Currently you have to first write to a Vec<u8>
, then write that.
let mut buf = Vec::<u8>::new();
writeln!(buf, "Hello world")?;
f.write_all(&buf).await?;
2 Likes
rjc2013
December 18, 2021, 10:02am
3
I suspected that might be the case.
Thanks!
alice
December 18, 2021, 10:02am
4
Note that this arguably removes the need for you to use a BufWriter
since you're already manually buffering with a vector. (or not, depends on how you use it)
1 Like
rjc2013
December 18, 2021, 9:33pm
5
For those finding this thread, I came up with this macro that encapsulates Alice's pattern:
// Example usage:
// use tokio::fs;
// let mut f = fs::File::create("hello.txt").await?;
// async_writeln!(f, "x = {}", 123)?;
macro_rules! async_writeln {
($dst: expr) => {
{
tokio::io::AsyncWriteExt::write_all(&mut $dst, b"\n").await
}
};
($dst: expr, $fmt: expr) => {
{
use std::io::Write;
let mut buf = Vec::<u8>::new();
writeln!(buf, $fmt)?;
tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
}
};
($dst: expr, $fmt: expr, $($arg: tt)*) => {
{
use std::io::Write;
let mut buf = Vec::<u8>::new();
writeln!(buf, $fmt, $( $arg )*)?;
tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
}
};
}
1 Like
system
Closed
March 18, 2022, 9:34pm
6
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.