Skip to main content

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}