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 Iterator for ChunkedFile<'_> { 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.is_empty()) } } 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 } }