How to discard some bytes from a stream


#1

I’m parsing a byte stream which consist of many head-body pairs.
The exact head size is known and they are the same. But the body size is described in head.
I need to read head part first by read_exact(), then read the body part and discard it because the body is useless for my work.

Now I can’t find a good way to do this, because body size is not sure in compiler time so i can’t use a array as buffer. And Vec can’t pass to read_exact(), if I convert it to &mut [u8] by as_slice(), the length of it is
always 0.

Finally, here is my code now:

fn parse(mut source: impl io::Read) {
    loop {
        let mut buf: [u8; META_SIZE] = [0; META_SIZE];
        source.read_exact(&mut buf).expect("read meta failed");
        // some code handle buf

        //I write these code to discard the body.
        let mut droped = 0;
        while droped < body_size {
            let mut b: [u8; 4096] = [0; 4096];
            let left_bytes_num = meta.body_size - droped;
            if left_bytes_num >= 4096 {
                source.read_exact(&mut b).expect("read body failed");
                droped += 4096;
            }else{
                source.read_exact(&mut b[0..(left_bytes_num as usize)]).expect("read body failed");
                droped += left_bytes_num;
            }
        }
    }
}

Is there any better way to deal with this situation? thanks

summary:

  1. need a way to read some bytes which length is determined in runtime;
  2. need a way to discard some bytes so that no copy to buffer action.

#2

You can first allocate reasonable size of array on the stack and repeatedly read to it until your body size is consumed. This sounds like stupid choice at first, but all those needless writes will easily be optimized out by compiler.


#3

I found a method to achieve the first requirement without using while.

for example, read n bytes from src, code will like this:

let mut buf = vec![0;n];
src.read(&mut buf.as_mut_slice()).unwrap();