1 use std::{ 2 fs::{self, File}, 3 io::{self, Read, Seek, Write}, 4 }; 5 6 use super::buffer::EditBuffer; 7 8 use std::path::PathBuf; 9 10 pub const BAK_SUFFIX: &'static str = ".heldbak"; 11 12 pub struct FileManager { 13 name: String, 14 file: File, 15 is_first_open: bool, 16 bak: Option<File>, 17 } 18 #[allow(unused)] 19 impl FileManager { new(file_path: String) -> io::Result<Self>20 pub fn new(file_path: String) -> io::Result<Self> { 21 let ifo_flag = !PathBuf::from(file_path.clone()).exists(); 22 23 let file = File::options() 24 .write(true) 25 .read(true) 26 .create(true) 27 .open(file_path.clone())?; 28 29 Ok(Self { 30 file, 31 is_first_open: ifo_flag, 32 name: file_path, 33 bak: None, 34 }) 35 } 36 init(&mut self, bak: bool) -> io::Result<EditBuffer>37 pub fn init(&mut self, bak: bool) -> io::Result<EditBuffer> { 38 let mut buf = Vec::new(); 39 // 是否备份 40 if bak { 41 self.do_bak(&mut buf)?; 42 } else { 43 self.file.read_to_end(&mut buf)?; 44 } 45 46 Ok(EditBuffer::new(buf)) 47 } 48 49 // 备份 do_bak(&mut self, buf: &mut Vec<u8>) -> io::Result<()>50 fn do_bak(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { 51 let mut bak = File::options() 52 .write(true) 53 .read(true) 54 .create(true) 55 .open(format!("{}{}", self.name, BAK_SUFFIX))?; 56 57 bak.set_len(0)?; 58 59 self.file.read_to_end(buf)?; 60 bak.write_all(&buf)?; 61 62 self.file.seek(io::SeekFrom::Start(0))?; 63 64 if self.bak.is_some() { 65 error!("The backup already exists. The operation may cause data loss."); 66 } 67 68 self.bak = Some(bak); 69 70 Ok(()) 71 } 72 store(&mut self, buf: &EditBuffer) -> io::Result<()>73 pub fn store(&mut self, buf: &EditBuffer) -> io::Result<()> { 74 let data = buf.all_buffer(); 75 76 self.file.set_len(0)?; 77 78 for (idx, line) in data.iter().enumerate() { 79 if idx == data.len() - 1 { 80 self.file.write(&line[..line.len()])?; 81 } else { 82 self.file.write(&line)?; 83 } 84 } 85 86 if self.bak.is_some() { 87 fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?; 88 } 89 self.is_first_open = false; 90 91 Ok(()) 92 } 93 is_first_open(&mut self) -> bool94 pub fn is_first_open(&mut self) -> bool { 95 self.is_first_open 96 } 97 delete_files(&mut self) -> io::Result<()>98 pub fn delete_files(&mut self) -> io::Result<()> { 99 if !self.name.is_empty() { 100 fs::remove_file(self.name.clone())?; 101 } 102 103 if self.bak.is_some() { 104 fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?; 105 } 106 Ok(()) 107 } 108 get_heldbak(&mut self) -> Option<File>109 pub fn get_heldbak(&mut self) -> Option<File> { 110 match self.bak.take() { 111 Some(file) => Some(file), 112 None => None, 113 } 114 } 115 restore(&mut self) -> io::Result<()>116 pub fn restore(&mut self) -> io::Result<()> { 117 if self.bak.is_some() { 118 let bak_file = self.bak.as_mut().unwrap(); 119 bak_file.seek(io::SeekFrom::Start(0)).unwrap(); 120 121 let mut buf = Vec::new(); 122 bak_file.read_to_end(&mut buf).unwrap(); 123 124 self.file.write_all(&buf)?; 125 126 self.file.seek(io::SeekFrom::Start(0))?; 127 bak_file.seek(io::SeekFrom::Start(0))?; 128 } 129 Ok(()) 130 } 131 } 132