use std::{ fs::File, io::{Read, Seek, SeekFrom}, path::PathBuf, }; use log::error; pub struct ChunkedFile<'t> { path: &'t PathBuf, cnum: u64, csize: usize, } impl<'t> ChunkedFile<'t> { pub(super) fn new(path: &'t PathBuf, chunk_size: usize) -> Self { Self { path, cnum: 0, csize: chunk_size, } } } impl<'t> Iterator for ChunkedFile<'t> { type Item = Chunk; fn next(&mut self) -> Option { let offset = { let csize: u64 = self.csize.try_into().unwrap(); self.cnum * csize }; let mut f = File::open(&self.path) .inspect_err(|e| error!("Error opening file: {}", e)) .ok()?; f.seek(SeekFrom::Start(offset)).ok()?; let mut bytes = vec![0; self.csize]; let read_len = f .read(&mut bytes) .inspect_err(|e| error!("Error reading file: {}", e)) .ok()?; bytes.truncate(read_len); self.cnum += 1; Some(Self::Item { offset, bytes }).filter(|c| c.bytes.len() > 0) } } pub struct Chunk { pub offset: u64, pub bytes: Vec, } impl Chunk { pub fn after(&self) -> u64 { let len: u64 = self.bytes.len().try_into().unwrap(); self.offset + len } }