如果 BufReader 取得流的所有权,我如何在其上读取和写入行?

If BufReader takes ownership of a stream, how can I read and write lines on it?

我想从 TCPStream 中读取一行,向其写入另一行,然后重复。问题是 BufReader::new 取得了我的 TCPStream 变量的所有权:

let stream = ...; // TCPStream

let reader = BufReader::new(stream); // moved its value

// can't use stream here anymore

有什么简单的解决方法?

你有几种可能性:

  • 不要使用 BufReader
  • 使用get_mut
  • 暂时从BufReader借用流
  • 完全丢弃 BufReader 并使用 into_inner
  • 恢复流

我个人建议不要使用 BufReader 除非你真的需要缓冲输入;对于单行来说似乎不值得。

否则,如果您完成了缓冲,您可以恢复底层流,如果没有,您可以暂时缓冲它。

警告请注意 BufReader 缓冲读取,因此当您 borrow/recover 内部流短路时缓冲数据;阅读是个问题,你的情况(写作)应该没问题。

解决方法:使用引用。

let mut stream = ...;
let reader = BufReader::new(&stream);
let writer = BufWriter::new(&stream);

说明

如果我们仔细观察 BufReader::new,我们会发现它接受类型为 R 的参数 inner,其中 R 只是实现的任何类型Read:

impl<R: Read> BufReader<R> {
    pub fn new(inner: R) -> BufReader<R> { ... }
}

然后我们看一下 Read 并看到这个实现:

impl<'a> Read for &'a TcpStream

所以我们可以只传递对 new 函数的引用,如下所示:

let reader = BufReader::new(&stream);

我们将对 BufWriterWrite 做同样的事情,并且会看到确实有这个实现:

impl<'a> Write for &'a TcpStream

所以我们可以再次使用不可变引用来创建 BufWriter