Strange behaviour when pass &mut Vec<u8> to Read::read()

I tried:

 pub fn get(&self) -> io::Result<String> {
        let rd = &mut self.file.borrow_mut().read;
        let mut data = Vec::new(); data)?;
        let data = String::from_utf8_lossy(&data).into_owned();

but Read::read() didn't add anything to the vector

Read::read accepts &mut [u8], not &mut Vec<u8>. To read to end, use Read::read_to_end instead which accepts &mut Vec<u8>. Also, because you are reading to string, you may also consider using Read::read_to_string.

Clippy will notice this problem: Clippy Lints.


but doesen't the compiler do the conversion?

Vec<u8> has an implementation of DerefMut which can be used to deref coerce &mut Vec<u8> into &mut [u8].

In this case because the vector is empty you end up with essentially passing &mut [] to read function which tells read to not actually read anything.

1 Like

I don't understand, shoulden't read() add bytes to the vector?

&mut [u8] cannot be resized, so it cannot grow to hold the additional data.

read_to_end and read_to_string specifically take &mut Vec<u8>, allowing them to resize (and potentially reallocate) when the buffer is filled.


Thank you!

1 Like

Beware that .read() returns a Result that you should check. On success the result contains the number of bytes read. Which may be less than the size of the given buffer.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.