1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
use memmap::MmapOptions; use std::fs::File; use std::thread; pub struct TailReader<T> { file_path: String, processor: T, } impl<T> TailReader<T> where T: Fn(String) { pub fn new(file_path: String, processor: T) -> TailReader<T> { TailReader { file_path, processor, } } pub fn tail(self) { let mut offset: usize = 0; let stop_char: u8 = "\n".as_bytes()[0]; let mut current_line = Vec::new(); loop { let file = match File::open(self.file_path.clone()) { Ok(n) => n, _ => return }; let mmap = unsafe { match MmapOptions::new().map(&file) { Ok(n) => n, _ => return } }; let mmap_len = mmap.len(); if mmap_len > offset { let bytes = match mmap.get(offset..mmap_len) { Some(n) => n, _ => continue }; for byte in bytes { if *byte == stop_char { (self.processor)(String::from_utf8(current_line).unwrap()); current_line = Vec::new(); } else { current_line.push(*byte); } offset += 1; } } else {} thread::sleep_ms(1000) } } }