notify icon indicating copy to clipboard operation
notify copied to clipboard

Receive Modify Event After using notify-debouncer-full

Open nihility23 opened this issue 1 year ago • 2 comments

My core code as below

    let mut debouncer = new_debouncer(Duration::from_secs(2), None, move |result: DebounceEventResult| {
        match result {
            Ok(events) => events.iter().for_each(|event|{
                match &event.kind {
                    EventKind::Any =>{},
                    EventKind::Create(_)=>{
                        info!("收到创建事件{}",event.paths.first().unwrap().to_str().unwrap());
                    } ,
                    EventKind::Modify(_)=>{
                        info!("收到修改事件{}",event.paths.first().unwrap().to_str().unwrap());
                    } ,

                    EventKind::Remove(_)=>{
                        
                    } ,
                    EventKind::Access(_)=>{},
                    EventKind::Other=>{},
                }

            }),
            Err(errors) => errors.iter().for_each(|err| error!("{err:?}")),
        }
    }).unwrap();

when I create a file , I will reveive modify event;

INFO [file_listener::watch::watch] 收到创建事件E:\test\filelisten\src\fddfd - 副本 (5).xml
INFO [file_listener::watch::watch] 收到修改事件E:\test\filelisten\src\fddfd - 副本 (5).xml

My cargo.toml config as below:

name = "file-listener"
version = "0.1.0"
edition = "2021"

[dependencies]
notify-debouncer-full = "0.5.0"
notify = "8.0.0"

nihility23 avatar Jan 29 '25 06:01 nihility23

What operating system are you using? And how are you creating the file?

You are receiving a Create and then a Modify event. Looks good to me.

dfaust avatar Jan 29 '25 10:01 dfaust

Operating system version: Windows 10 Professional

I create the file by two ways: 1: Ctrl+C and Ctrl+V on watching the dir. A file named a.xml on the "E:\test\filelisten\src" ,when I do Ctrl+C/V, will create a new file named a - 副本.xml,I will gain:

    INFO [file_listener] 收到创建事件E:\test\filelisten\src\a - 副本.xml
    INFO [file_listener] 收到修改事件E:\test\filelisten\src\a - 副本.xml

2: Copy file named 'b.xml' from the other dir, I will gain:

INFO [file_listener] 收到创建事件E:\test\filelisten\src\b.xml
INFO [file_listener] 收到修改事件E:\test\filelisten\src\b.xml

I simplify the code, and the whole code as below main.rs

use std::time::Duration;

use std::path::Path;

use log::{error,info};
use notify_debouncer_full::{notify::*, new_debouncer, DebounceEventResult};
use flexi_logger::{Logger, FileSpec, Criterion, Naming, Cleanup, WriteMode, Duplicate, detailed_format};


pub fn init_log(log_lvl : &str){
    println!("日志级别[{}]",&log_lvl);
    // 初始化日志记录,配置输出到文件,设置文件大小限制和滚动日志
    let _ = Logger::try_with_str(&log_lvl)
    .unwrap()
    .log_to_file(
        FileSpec::default()
            .directory("logs") 
            .basename("file_listener") 
            .suffix("log")     
    )
    .rotate(
        Criterion::Age(flexi_logger::Age::Day), 
        Naming::Timestamps,        
        Cleanup::KeepLogFiles(3),   
    )
    .write_mode(WriteMode::BufferAndFlush) 
    .duplicate_to_stdout(Duplicate::All)  
    .format_for_files(detailed_format)    
    .start()
    .unwrap();
}

pub fn start_watch(){

    let mut debouncer = new_debouncer(Duration::from_secs(2), None, move |result: DebounceEventResult| {
        match result {
            Ok(events) => events.iter().for_each(|event|{
                match &event.kind {
                    EventKind::Any =>{},
                    EventKind::Create(_)=>{
                        info!("收到创建事件{}",event.paths.first().unwrap().to_str().unwrap());
                    } ,
                    EventKind::Modify(_)=>{
                        info!("收到修改事件{}",event.paths.first().unwrap().to_str().unwrap());
                    } ,

                    EventKind::Remove(_)=>{
                        
                    } ,
                    EventKind::Access(_)=>{},
                    EventKind::Other=>{},
                }

            }),
            Err(errors) => errors.iter().for_each(|err| error!("{err:?}")),
        }
    }).unwrap();


    debouncer.watch(Path::new("E:\\test\\filelisten\\src"), RecursiveMode::Recursive).unwrap();


    loop {
        std::thread::sleep(Duration::from_millis(100));
    }
}

fn main() {
    file_listener::log::log::init_log("info");
    // 开启监听
    start_watch();

    loop {
        std::thread::sleep(Duration::from_millis(1000));
    }
}

cargo.toml

[package]
name = "file-listener"
version = "0.1.0"
edition = "2021"

[dependencies]
log = "0.4"
flexi_logger = "0.22"
notify-debouncer-full = "0.5.0"
notify = "8.0.0"

in addition, I use notify-debouncer-mini, don't receive Modify Event, but can't gain event kind

nihility23 avatar Jan 29 '25 12:01 nihility23

I am also experiencing this issue.

The documentation for notify-debouncer-full states "Doesn’t emit Modify events after a Create event". However, I am still getting Modify events after Create events are fired.

I add a single file to the watched directory with this code running:

use config::{Config, File};
use notify_debouncer_full::{new_debouncer, DebouncedEvent, notify::*};
use std::path::Path;
use std::time::Duration;
use std::sync::mpsc::channel;

fn main() {
    let config = Config::builder().add_source(File::with_name("config")).build().expect(CONFIG_FILE_ERROR);
    let song_dir_path: String = config.get("song_dir_path").expect(CONFIG_FILE_READ_ERROR);

    let (event_sender, event_receiver) = channel();

    let mut debounced_dir_watcher = new_debouncer(Duration::from_secs(2), None, event_sender).expect(DIR_WATCHER_CREATE_ERROR);
    debounced_dir_watcher.watch(Path::new(&song_dir_path), RecursiveMode::NonRecursive).expect(DIR_WATCHER_WATCH_ERROR);

    for res in event_receiver {
        match res {
            Ok(e) => handle_directory_events(e),
            Err(e) => println!("Song dir event watcher error: {e:?}")
        }
        println!();
    }
}

fn handle_directory_events(e: Vec<DebouncedEvent>) {
    println!("Events: {:?}\n", e);
}

And this is the output I receive:

[DebouncedEvent { event: Event { kind: Create(Any), paths: ["C:\Users\Kepler\songs\Stranger.mp3"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }, time: Instant { t: 235002.8305774s } }, DebouncedEvent { event: Event { kind: Modify(Any), paths: ["C:\Users\Kepler\songs\Stranger.mp3"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }, time: Instant { t: 235002.8308492s } }]

KeplerIO avatar Jul 12 '25 03:07 KeplerIO