mdf4_rs/index/file_range_reader.rs
1//! [`FileRangeReader`].
2
3#[allow(unused_imports)]
4use super::*;
5use crate::{Error, Result};
6use std::io::{Read, Seek, SeekFrom};
7
8/// Simple file reader that seeks and reads for each request.
9///
10/// This reader has minimal memory overhead but may have higher I/O latency
11/// when reading many small ranges. For sequential access patterns, consider
12/// using [`BufferedRangeReader`] instead.
13///
14/// # Example
15///
16/// ```no_run
17/// use mdf4_rs::{MdfIndex, FileRangeReader};
18///
19/// let index = MdfIndex::from_file_streaming("data.mf4")?;
20/// let mut reader = FileRangeReader::new("data.mf4")?;
21/// let values = index.read_channel_values(0, 0, &mut reader)?;
22/// # Ok::<(), mdf4_rs::Error>(())
23/// ```
24pub struct FileRangeReader {
25 file: std::fs::File,
26}
27impl FileRangeReader {
28 /// Open a file for range reading.
29 ///
30 /// # Arguments
31 /// * `file_path` - Path to the file
32 ///
33 /// # Errors
34 /// Returns an error if the file cannot be opened.
35 pub fn new(file_path: &str) -> Result<Self> {
36 let file = std::fs::File::open(file_path).map_err(Error::IOError)?;
37 Ok(Self { file })
38 }
39}
40impl ByteRangeReader for FileRangeReader {
41 type Error = Error;
42
43 fn read_range(
44 &mut self,
45 offset: u64,
46 length: u64,
47 ) -> core::result::Result<Vec<u8>, Self::Error> {
48 self.file
49 .seek(SeekFrom::Start(offset))
50 .map_err(Error::IOError)?;
51
52 let mut buffer = vec![0u8; length as usize];
53 self.file.read_exact(&mut buffer).map_err(Error::IOError)?;
54
55 Ok(buffer)
56 }
57}