61 lines
1.3 KiB
Rust
61 lines
1.3 KiB
Rust
|
|
use std::{
|
||
|
|
fs,
|
||
|
|
io::{self, Read, Seek},
|
||
|
|
mem,
|
||
|
|
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<Self::Item> {
|
||
|
|
let offset = {
|
||
|
|
let csize: u64 = self.csize.try_into().unwrap();
|
||
|
|
self.cnum * csize
|
||
|
|
};
|
||
|
|
|
||
|
|
let mut f = fs::File::open(&self.path)
|
||
|
|
.inspect_err(|e| error!("Error opening file: {}", e))
|
||
|
|
.ok()?;
|
||
|
|
f.seek(io::SeekFrom::Start(offset)).ok()?;
|
||
|
|
|
||
|
|
let mut buffer = vec![0; self.csize];
|
||
|
|
let read_len = f
|
||
|
|
.read(&mut buffer)
|
||
|
|
.inspect_err(|e| error!("Error reading file: {}", e))
|
||
|
|
.ok()?;
|
||
|
|
buffer.truncate(read_len);
|
||
|
|
|
||
|
|
self.cnum += 1;
|
||
|
|
|
||
|
|
Some(Self::Item {
|
||
|
|
offset: offset.try_into().unwrap(),
|
||
|
|
bytes: buffer,
|
||
|
|
})
|
||
|
|
.filter(|c| c.bytes.len() > 0)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub struct Chunk {
|
||
|
|
pub offset: usize,
|
||
|
|
pub bytes: Vec<u8>,
|
||
|
|
}
|