如何在 rust 中阻止,直到文件有更多数据

How do you block in rust until a file has more data

提问人:Adrodoc 提问时间:7/11/2021 最后编辑:Adrodoc 更新时间:3/2/2023 访问量:561

问:

我正在使用 BufRead::read_line 自动读取由另一个应用程序编写的日志文件:

let file = File::open("foo.log")?;
let mut reader = BufReader::new(file);
let mut line = String::new();
loop {
    line.clear();
    let size = reader.read_line(&mut line)?;
    if size != 0 {
        // ... process line
    } else {
        // How do I block until reader is no longer at EOF?
    }
}

当我到达文件末尾时,我想等到更多数据可用。 有没有比忙着等待更好的选择?sleep(Duration::from_millis(50));

我已经研究了通知 crate 以等待写入事件,但看起来在 Windows 上,这些事件仅在文件关闭时发生(即使使用原始 API 时),但在我的情况下,应用程序会保持其日志文件打开状态,直到它被关闭。

使用也可以(甚至首选)。async

Windows 文件 生锈 IO EOF

评论

0赞 rodrigo 7/12/2021
值得一提的是,GNU 实现使用 if 可用,然后使用 .AFAIK 'inotifyp 在 Windows 上不可用,所以......给你。tail -finotifysleep

答:

0赞 Riton Elion 7/11/2021 #1

似乎有一个 libaray 可以满足您的要求:https://crates.io/crates/notify 但我不确定它是否异步。

评论

0赞 Adrodoc 7/12/2021
不幸的是,这似乎不是 Windows 的解决方案。似乎我在您阅读时编辑了我的问题,对不起:)
1赞 ptdecker 3/2/2023 #2

这是我制定的基于池化的方法的草图。您可以将其与文件的只读打开相结合,查找到最后一个已知大小,然后读取任何更改的数据。显然,这只是一种方法的草图。而且,它仍然使用线程睡眠。但是,我没有找到更好的方法来解决同样的问题。我很想知道你是否曾经想出一个解决方案。

use std::{fs, thread, time};
use std::time::SystemTime;

fn main() {
    let pool_interval = 1; // seconds
    let path = "../path/logs/logfile.log".to_string();
    println!("watching {}", path);
    let mut last_modified:u64 = 0;
    loop {
        let attr = fs::metadata(&path).unwrap();
        let modified = attr.modified().unwrap().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
        if modified != last_modified {
            last_modified = modified;
            let filesize = attr.len();
            println!("modified: {:?}, new size: {:?}", modified, filesize);
        }
        thread::sleep(time::Duration::from_secs(pool_interval))
    }
}

评论

3赞 Adrodoc 3/3/2023
我们最终使用的解决方案是通知箱和轮询的混合。我们等待写入事件,但有超时。如果超时期间没有发生任何事件,我们仍然会继续读取。我们还使阅读器保持打开状态,以确保在日志文件轮换时不会错过最后一行。幸运的是,日志文件轮换总是会产生创建事件,即使在 Windows 上也是如此。发生这种情况时,我们重新打开路径以获取新文件的句柄。代码可以在这里看到:github.com/vanilla-technologies/minect/blob/...
0赞 ptdecker 3/4/2023
@Adrodoc感谢您跟进我