I am trying to create an iterator for reading chunks of size chunk_size from a file. I have the following solution:
fn read_chunks<R: std::io::Read>(file: &mut R, chunk_size: usize) {
let file_bytes: Vec<u8> = file.bytes().flatten().collect();
let chunk_iter = file_bytes.chunks(chunk_size);
// rest of code omitted ...
}
It is however too slow for large files. I notice the following is much faster:
fn read_chunks<R: std::io::Read>(file: &mut R, chunk_size: usize) {
loop {
let mut buf = vec![0u8; chunk_size]
match file.read_exact(&mut buf) {
Ok(()) => {
// code for handling each chunk omitted
}
Err(e) if e.kind() == std::io::error::ErrorKind::UnexpectedEoF => {
break;
}
}
}
}
But how do I return it as an iterator? I want to have it like chunk_iter where I can use it in conjunction with other iterators.
intuitively I want to write something like this (similar to a generator in python):
fn read_chunks_iter<'a, R: std::io::Read>(file &mut R, chunk_size: usize)
-> Iterator<Item=&'a [u8]>
{
loop {
let mut buf = vec![0u8; chunk_size]
match file.read_exact(&mut buf) {
Ok(()) => {
yield buf;
}
Err(e) if e.kind() == std::io::error::ErrorKind::UnexpectedEoF => {
break;
}
}
}
}