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
use memmap::MmapOptions; use std::fs::File; use std::thread; use std::str; pub struct TailReader<'a, T> { file_path: &'a str, processor: T, } impl<'a, T> TailReader<'a, T> where T: Fn(String) { pub fn new(file_path: &'a str, 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 = File::open(self.file_path).unwrap(); let mmap = unsafe { MmapOptions::new().map(&file).unwrap() }; let mmap_len = mmap.len(); if mmap_len > offset { let bytes = mmap.get(offset..mmap_len).unwrap(); 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; } } thread::sleep_ms(250) } } }