use std::convert::TryFrom;
use std::fs::File;
use std::io::Write;
#[cfg(target_family = "unix")]
use std::os::unix::fs::FileExt
;
#[cfg(target_family = "windows")]
use std::os::windows::fs::FileExt;
pub struct BufferReader {
pub file: File,
pub file_len: u64,
pub offset: u64,
pub buffer_size: u64,
}
impl BufferReader {
#[must_use]
pub fn read_next(&mut self) -> Vec<u8> {
let buffer_len: usize;
if self.offset + self.buffer_size < self.file_len {
buffer_len = usize::try_from(self.buffer_size).unwrap();
} else {
buffer_len = usize::try_from(self.file_len - self.offset).unwrap();
}
let mut buffer = vec![0; buffer_len];
#[cfg(target_family = "unix")]
self.file.read_exact_at(&mut buffer, self.offset).unwrap();
#[cfg(target_family = "windows")]
self.file.seek_read(&mut buffer, self.offset).unwrap();
self.offset += &self.buffer_size;
buffer
}
#[must_use]
pub fn write_next(mut self, buffer: &[u8]) -> Self {
#[cfg(target_family = "windows")]
self.file.seek_write(buffer, self.offset).unwrap();
#[cfg(target_family = "unix")]
self.file.write_all(buffer).unwrap();
self.offset += self.buffer_size;
self
}
#[must_use]
pub fn new(file: File, buffer_size: u64) -> Self {
#[allow(clippy::cast_possible_truncation)] Self {
file,
file_len: 0,
offset: 0,
buffer_size,
}
}
}
pub fn read_file_in_chunks_and_write() {
const BUFFER_SIZE: u64 = 100_000;
#[allow(clippy::cast_possible_truncation)] const BUFF_U: usize = BUFFER_SIZE as usize;
let file = File::open("./src/assets/100MB.bin").unwrap();
let mut new_file = File::create("./src/assets/new.bin").unwrap();
let file_len = file.metadata().unwrap().len();
let mut offset = 0;
let buff_count = file_len / BUFFER_SIZE;
let mut buffer = [0; BUFF_U];
for _ in 0..buff_count {
#[cfg(target_family = "unix")]
file.read_exact_at(&mut buffer, offset).unwrap();
#[cfg(target_family = "windows")]
file.seek_read(&mut buffer, offset).unwrap();
new_file.write_all(&buffer).unwrap();
offset += BUFFER_SIZE;
}
let remain = file_len - offset;
#[allow(clippy::cast_possible_truncation)] let mut buffer_last = vec![0; remain as usize];
#[cfg(target_family = "unix")]
file.read_exact_at(&mut buffer_last, offset).unwrap();
#[cfg(target_family = "windows")]
file.seek_read(&mut buffer_last, offset).unwrap();
new_file.write_all(&buffer_last).unwrap();
}