如何从流中读取特定数量的字节?

bus*_*ter 11 rust

我有一个带有BufStream<T>where 的结构T: Read+Write.该BufStream可以是一个TcpStream,我想从中读取n个字节.在预定义的缓冲区中不是固定数量的字节,但我有一个字符串/流,它指示下一个要读取的字节数.

有一个很好的方法吗?

rsp*_*eer 8

自Rust 1.6以来,Read::read_exact可以用来做到这一点.If bytes_to_read是您需要读取的字节数,可能在运行时确定,并且reader是要读取的流:

let mut buf = vec![0u8; bytes_to_read];
reader.read_exact(&mut buf)?;
Run Code Online (Sandbox Code Playgroud)

read_exact文档中我不清楚的部分是目标缓冲区可以动态分配Vec.

感谢Rust Gitter社区指导我这个解决方案.

  • @Nanos希望您已经在其他地方解决了这个问题,但是,答案是您需要先用一些值填充“Vec”(或者不安全地设置我猜的长度)。`vec![0u8; 上面使用的 bytes_to_read]` 用 `bytes_to_read` 零填充 `Vec`。 (5认同)
  • 这在文档中指定:“如果此函数在完全填充缓冲区之前遇到“文件结尾”,它将返回类型为 `ErrorKind::UnexpectedEof` 的错误。 (3认同)

She*_*ter 6

听起来像您想要的Read::takeRead::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)
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 确实如此,但“读者”可以是一个`&amp;mut R`,即对另一个读者的临时可变引用。Take 使用按值 API,以便支持所有用例。这个模型出现在锈迹的不同角落。 (2认同)
  • @Kaeros [`take`](https://doc.rust-lang.org/std/io/trait.Read.html#method.take) 来自 [`Read`](https://doc.rust- lang.org/std/io/trait.Read.html) 和 [`Read` 是为实现 `Read` 的类型的任何可变引用而实现的](https://doc.rust-lang.org/1.37.0 /std/io/trait.Read.html#impl-Read-12)。另请参阅[在函数之间传递时引用 BufReader/BufWriter 的惯用方式是什么?](/sf/ask/2762496621/); (2认同)