我有一个函数,其签名是这样的:
pub fn handle_decode(buf: &mut bytes::BytesMut) -> anyhow::Result<DataType> {}
它将在处理不同网络传输协议的例程之间共享。我使用
bytes
包的原因是它可以很好地处理字节序和浅拷贝等问题。以正确的顺序挑选字节并以低廉的成本“克隆”它们非常好。
话虽这么说,在 TCP 例程中,我希望使用
BufReader<TcpStream>
来应对从流中拾取数据时重复系统调用 read()
的开销。
有什么方法可以将
bytes::BufMut
与缓冲读取器结合使用,以获得两全其美的效果吗?
最小示例:
use anyhow::Context;
use std::io::BufReader;
use std::net::TcpListener;
fn bind_accept() -> anyhow::Result<()> {
fn handle_decode(buf: &mut bytes::BytesMut) -> anyhow::Result<()> {
unimplemented!()
}
let mut l = TcpListener::bind("1234")?;
let (sock, _) = l.accept().context("should bind to provided port")?;
let bufreader = BufReader::new(sock);
let mut buf = bytes::BytesMut::with_capacity(1024);
// This line will not work in this current state
handle_decode(&mut bufreader)
}
BytesMut
已经缓冲了它的内容,不需要另一个缓冲区。您可以使用 BytesMut
或 BufReader
,不能同时使用。
使用特征
BufMut
,您可以使用writer
,这将返回一个实现从std写入的包装器。然后你需要自己实现 std 的 BufReader
的作用,我没有找到任何已经为你做的事情。或者您可能更喜欢直接使用 BufMut
特征而不是 std 特征。
use anyhow::Context;
use std::net::TcpListener;
use bytes::BytesMut;
fn bind_accept() -> anyhow::Result<()> {
fn handle_decode(buf: &mut bytes::BytesMut) -> anyhow::Result<()> {
unimplemented!()
}
let l = TcpListener::bind("1234")?;
let (sock, _) = l.accept().context("should bind to provided port")?;
let mut buf = BytesMut::with_capacity(1024);
// read socket with BytesMut as buffer here
handle_decode(&mut buf)
}