You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Read::read_exact无法填充Vec::with_capacity()创建的缓冲区?

Why does read_exact fail to fill my Vec even though it has enough capacity?

I wrote this Rust code expecting read_exact to fill my Vec with 4 bytes, but it panics because the Vec's length remains 0:

use std::io::{Cursor, BufReader, Read};
fn main() {
    let string = String::from("Cello");
    let bytes = string.as_bytes();
    let cursor = Cursor::new(bytes);
    let mut reader = BufReader::new(cursor);
    let mut buf: Vec<u8> = Vec::with_capacity(4);
    assert_eq!(4, buf.capacity());
    reader.read_exact(&mut buf);
    assert_eq!(4, buf.len());
    //thread 'main' panicked at 'assertion failed: `(left == right)`
    //left: `4`, right: `0`'
}

According to the documentation for std::io::read_exact, this method "reads exactly enough bytes to fill buf". But even though my Vec has a capacity of 4 bytes, no bytes are being read into it. Why is this happening?


The Root Cause: Confusing Capacity vs. Length

You're mixing up two key properties of a Vec:

  • Capacity: The total amount of memory pre-allocated for the Vec to hold elements without reallocating. This is what Vec::with_capacity(4) sets to 4.
  • Length: The number of actual elements currently stored in the Vec. When you create a Vec with with_capacity, its length starts at 0—it's an empty Vec with space to grow, but no elements yet.

When you pass &mut buf to read_exact, Rust converts this into a &mut [u8] slice. Slices are defined by their length (not capacity), so this slice has a length of 0. read_exact does exactly what it says: it reads exactly the number of bytes equal to the slice's length—which in this case is 0. No bytes are read, so your Vec's length stays at 0, triggering the panic.

How to Fix It

You need to ensure the slice passed to read_exact has a length of 4 (the number of bytes you want to read). There are two straightforward ways to do this:

1. Initialize the Vec with a fixed length

Create a Vec that already has 4 elements (initialized to 0, for example) using vec![0u8; 4]:

use std::io::{Cursor, BufReader, Read};
fn main() {
    let string = String::from("Cello");
    let bytes = string.as_bytes();
    let cursor = Cursor::new(bytes);
    let mut reader = BufReader::new(cursor);
    let mut buf = vec![0u8; 4]; // Vec starts with length 4
    assert_eq!(4, buf.len());
    reader.read_exact(&mut buf).unwrap(); // Always handle IO errors in real code!
    assert_eq!(4, buf.len());
    assert_eq!(buf, b"Cello"[0..4]); // Verify we got the first 4 bytes of "Cello"
}

2. Resize the Vec before calling read_exact

If you already have a Vec with sufficient capacity, you can set its length to 4 using resize:

use std::io::{Cursor, BufReader, Read};
fn main() {
    let string = String::from("Cello");
    let bytes = string.as_bytes();
    let cursor = Cursor::new(bytes);
    let mut reader = BufReader::new(cursor);
    let mut buf: Vec<u8> = Vec::with_capacity(4);
    buf.resize(4, 0); // Set length to 4, filling new slots with 0
    assert_eq!(4, buf.len());
    reader.read_exact(&mut buf).unwrap();
    assert_eq!(4, buf.len());
    assert_eq!(buf, b"Cello"[0..4]);
}

Key Takeaway

read_exact doesn't care about your Vec's capacity—it only looks at the length of the slice you pass to it. Capacity is just a performance optimization to avoid reallocations; it doesn't affect how much data read_exact will attempt to read.

内容的提问来源于stack exchange,提问作者abipip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:07:38