我有一个结构与BufStream<T>
其中T: Read+Write
。 BufStream
可以是TcpStream
,我想从中读取n个字节。 在预定义的缓冲区中不是固定数量的字节,但是我有一个字符串/流,指示接下来要读取的字节数。如何从流中读取特定数量的字节?
有没有一个很好的方法来做到这一点?
我有一个结构与BufStream<T>
其中T: Read+Write
。 BufStream
可以是TcpStream
,我想从中读取n个字节。 在预定义的缓冲区中不是固定数量的字节,但是我有一个字符串/流,指示接下来要读取的字节数。如何从流中读取特定数量的字节?
有没有一个很好的方法来做到这一点?
这听起来像你想Read::take
和Read::read_to_end
:
use std::io::prelude::*;
use std::io::BufReader;
use std::str;
fn read_n<R>(reader: R, bytes_to_read: u64) -> Vec<u8>
where
R: Read,
{
let mut buf = vec![];
let mut chunk = reader.take(bytes_to_read);
// Do appropriate error handling for your situation
let n = chunk.read_to_end(&mut buf).expect("Didn't read enough");
assert_eq!(bytes_to_read as usize, n);
buf
}
fn main() {
let input_data = b"hello world";
let mut reader = BufReader::new(&input_data[..]);
let first = read_n(&mut reader, 5);
let _ = read_n(&mut reader, 1);
let second = read_n(&mut reader, 5);
println!(
"{:?}, {:?}",
str::from_utf8(&first),
str::from_utf8(&second)
);
}
由于锈1.6,Read::read_exact
可用来做到这一点。如果bytes_to_read
是你需要读取的字节,可能在运行时确定的数量,并且reader
是流从阅读:
let mut buf = vec![0u8; bytes_to_read];
reader.read_exact(&mut buf)?;
的一部分,这不是很清楚,我从read_exact
文档是目标缓冲区可以是动态分配的Vec
。
感谢Rust Gitter社区为我指出了这个解决方案。
谢谢..不采取()消耗读者? 我的用例是,我有一个tcpstream(结构的一部分),我从中读取行。有时候,我不需要读取一行,而是读取特定数量的字节。之后,我需要再读一遍...... – buster
它的确如此,但“读者”可以是一个'&mut R',即对另一个读者的临时可变引用。 Take使用按值API,以便支持所有用例。这个模型出现在锈蚀的一些不同角落。 – bluss
@buster as bluss指出,'&mut R'也实现了'Read'特性。我的例子使用它来达到良好的效果 - 这就是为什么我在例子的主要方法中传入'&mut reader'。 – Shepmaster