in core/src/services/fs/backend.rs [509:567]
fn blocking_read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::BlockingReader)> {
use oio::BlockingRead;
let p = self.root.join(path.trim_end_matches('/'));
let mut f = std::fs::OpenOptions::new()
.read(true)
.open(p)
.map_err(parse_io_error)?;
let total_length = if self.enable_path_check {
// Get fs metadata of file at given path, ensuring it is not a false-positive due to slash normalization.
let meta = f.metadata().map_err(parse_io_error)?;
if meta.is_dir() != path.ends_with('/') {
return Err(Error::new(
ErrorKind::NotFound,
"file mode is not match with its path",
));
}
if meta.is_dir() {
return Err(Error::new(
ErrorKind::IsADirectory,
"given path is a directory",
));
}
meta.len()
} else {
use std::io::Seek;
f.seek(SeekFrom::End(0)).map_err(parse_io_error)?
};
let br = args.range();
let (start, end) = match (br.offset(), br.size()) {
// Read a specific range.
(Some(offset), Some(size)) => (offset, min(offset + size, total_length)),
// Read from offset.
(Some(offset), None) => (offset, total_length),
// Read the last size bytes.
(None, Some(size)) => (
if total_length > size {
total_length - size
} else {
0
},
total_length,
),
// Read the whole file.
(None, None) => (0, total_length),
};
let mut r: oio::FromFileReader<std::fs::File> = oio::into_read_from_file(f, start, end);
// Rewind to make sure we are on the correct offset.
r.seek(SeekFrom::Start(0))?;
Ok((RpRead::new(end - start), r))
}