You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向notify-rs监听器回调传递额外数据的相关技术问题

解决Rust CLI文件监听转译的问题

一、处理notify的回调参数传递与主程序终止问题

notify的回调运行在独立线程中,要共享参数需使用线程安全容器,同时要给主线程添加阻塞逻辑避免提前终止:

方案1:用通道替代回调(更适合新手)

notify支持通过通道接收事件,所有逻辑都在主线程处理,无需复杂的线程安全处理:

use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;
use std::fs::File;
use std::io::Write;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 解析CLI参数,替换为你的实际配置
    let input_file = "input.txt".to_string();
    let mut output_file = File::create("output.txt")?;
    let settings = /* 你的转译配置 */;

    // 创建事件通道
    let (tx, rx) = channel();

    // 绑定通道创建watcher
    let mut watcher = RecommendedWatcher::new(tx, notify::Config::default())?;
    watcher.watch(input_file.as_ref(), RecursiveMode::NonRecursive)?;

    // 主线程阻塞循环,接收事件并处理转译
    for res in rx {
        match res {
            Ok(event) => {
                println!("文件变更: {:?}", event);
                // 执行转译逻辑
                let content = std::fs::read_to_string(&input_file)?;
                let translated = translate_content(&content, &settings);
                output_file.set_len(0)?;
                output_file.write_all(translated.as_bytes())?;
                output_file.flush()?;
            }
            Err(e) => println!("监听错误: {:?}", e),
        }
    }

    Ok(())
}

fn translate_content(content: &str, settings: &/* 你的配置类型 */) -> String {
    // 替换为你的实际转译逻辑
    content.to_uppercase()
}

方案2:回调方式传递线程安全状态

如果一定要用回调,需将参数包装为Arc<Mutex<T>>实现线程间共享,同时让主线程阻塞:

use notify::{RecommendedWatcher, RecursiveMode, Watcher, Event};
use std::sync::{Arc, Mutex};
use std::fs::File;
use std::io::Write;

// 封装需要共享的状态
struct AppState {
    settings: /* 你的配置类型 */,
    input_file: String,
    output_file: Box<dyn Write + Send + Sync + 'static>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input_file = "input.txt".to_string();
    let output_file = Box::new(File::create("output.txt")?) as Box<dyn Write + Send + Sync>;
    let settings = /* 你的转译配置 */;

    // 包装为线程安全的共享状态
    let state = Arc::new(Mutex::new(AppState {
        settings,
        input_file,
        output_file,
    }));
    let state_clone = Arc::clone(&state);

    // 创建带回调的watcher
    let mut watcher = RecommendedWatcher::new(move |res: Result<Event, notify::Error>| {
        match res {
            Ok(event) => {
                let mut state = state_clone.lock().unwrap();
                // 执行转译逻辑
                let content = std::fs::read_to_string(&state.input_file).unwrap();
                let translated = translate_content(&content, &state.settings);
                state.output_file.set_len(0).unwrap();
                state.output_file.write_all(translated.as_bytes()).unwrap();
                state.output_file.flush().unwrap();
            }
            Err(e) => println!("监听错误: {:?}", e),
        }
    }, notify::Config::default())?;

    watcher.watch(state.lock().unwrap().input_file.as_ref(), RecursiveMode::NonRecursive)?;

    // 让主线程保持阻塞
    std::thread::park();

    Ok(())
}

fn translate_content(content: &str, settings: &/* 你的配置类型 */) -> String {
    // 替换为你的实际转译逻辑
    content.to_uppercase()
}

二、更适配的替代库

如果你偏好“阻塞式检查变更”的体验,可以试试以下库:

  • hotwatch:基于notify的轻量封装,API简洁,支持直接捕获环境变量,新手友好。示例代码:
use hotwatch::{Hotwatch, Event};
use std::fs::File;
use std::io::Write;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input_file = "input.txt".to_string();
    let mut output_file = File::create("output.txt")?;
    let settings = /* 你的转译配置 */;

    let mut hotwatch = Hotwatch::new()?;
    hotwatch.watch(&input_file, move |event: Event| {
        if let Event::Write(_) = event {
            let content = std::fs::read_to_string(&input_file).unwrap();
            let translated = translate_content(&content, &settings);
            output_file.set_len(0).unwrap();
            output_file.write_all(translated.as_bytes()).unwrap();
            output_file.flush().unwrap();
        }
    })?;

    // 阻塞主线程保持监听
    loop {
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
}

fn translate_content(content: &str, settings: &/* 你的配置类型 */) -> String {
    // 替换为你的实际转译逻辑
    content.to_uppercase()
}
  • inotify:仅支持Linux平台,底层API直接,支持阻塞式读取事件,适合对性能有要求的场景。

内容的提问来源于stack exchange,提问作者Leonard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:03:11