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

dra*_*tis 14 tcp tcp-ip rust

我想从a读取一行TCPStream,再写一行,然后重复.问题是BufReader::new获取我的TCPStream变量的所有权:

let stream = ...; // TCPStream

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

// can't use stream here anymore
Run Code Online (Sandbox Code Playgroud)

什么是简单的解决方案?

Luk*_*odt 21

解决方案:使用引用.

let mut stream = ...;
let reader = BufReader::new(&stream);
let writer = BufWriter::new(&stream);
Run Code Online (Sandbox Code Playgroud)

说明

如果我们仔细看一下BufReader::new,我们会看到它需要一个inner类型的参数R,其中R只有任何类型的实现Read:

impl<R: Read> BufReader<R> {
    pub fn new(inner: R) -> BufReader<R> { ... }
}
Run Code Online (Sandbox Code Playgroud)

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

impl<'a> Read for &'a TcpStream
Run Code Online (Sandbox Code Playgroud)

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

let reader = BufReader::new(&stream);
Run Code Online (Sandbox Code Playgroud)

我们会做同样BufWriterWrite和会看到,确实有这样实现:

impl<'a> Write for &'a TcpStream
Run Code Online (Sandbox Code Playgroud)

因此,我们可以再次使用不可变引用来创建BufWriter.

  • 那是......出乎意料的.还不错,非常好! (2认同)

Mat*_* M. 6

你有几种可能性:

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

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

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

注意请注意BufReader缓冲读取,因此当您借用/恢复内部流时,您会短路缓冲的数据;对于阅读来说这是一个问题,就你的情况(写作)来说应该没问题。