1 use std::{ 2 fs::{self, File}, 3 io::{self, Read, Seek, Write}, 4 }; 5 6 use super::buffer::EditBuffer; 7 8 pub const BAK_SUFFIX: &'static str = ".heldbak"; 9 10 pub struct FileManager { 11 name: String, 12 file: File, 13 bak: Option<File>, 14 } 15 16 impl FileManager { 17 pub fn new(file_path: String) -> io::Result<Self> { 18 let file = File::options() 19 .write(true) 20 .read(true) 21 .create(true) 22 .open(file_path.clone())?; 23 24 Ok(Self { 25 file, 26 name: file_path, 27 bak: None, 28 }) 29 } 30 31 pub fn init(&mut self, bak: bool) -> io::Result<EditBuffer> { 32 let mut buf = Vec::new(); 33 // 是否备份 34 if bak { 35 self.do_bak(&mut buf)?; 36 } else { 37 self.file.read_to_end(&mut buf)?; 38 } 39 40 Ok(EditBuffer::new(buf)) 41 } 42 43 // 备份 44 fn do_bak(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { 45 let mut bak = File::options() 46 .write(true) 47 .read(true) 48 .create(true) 49 .open(format!("{}{}", self.name, BAK_SUFFIX))?; 50 51 bak.set_len(0)?; 52 53 self.file.read_to_end(buf)?; 54 bak.write_all(&buf)?; 55 56 self.file.seek(io::SeekFrom::Start(0))?; 57 58 if self.bak.is_some() { 59 error!("The backup already exists. The operation may cause data loss."); 60 } 61 62 self.bak = Some(bak); 63 64 Ok(()) 65 } 66 67 pub fn store(&mut self, buf: &EditBuffer) -> io::Result<()> { 68 let data = buf.all_buffer(); 69 70 self.file.set_len(0)?; 71 72 for (idx, line) in data.iter().enumerate() { 73 if idx == data.len() - 1 { 74 self.file.write(&line[..line.len()])?; 75 } else { 76 self.file.write(&line)?; 77 } 78 } 79 80 if self.bak.is_some() { 81 fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?; 82 } 83 84 Ok(()) 85 } 86 } 87