rust 39 lines · 6 steps

Polling a directory for new files in Rust

A DirectoryWatcher scans a folder on an interval and fires a callback the first time it sees each file.

Explained by highlit
1use std::collections::HashSet;
2use std::fs;
3use std::path::{Path, PathBuf};
4use std::thread;
5use std::time::Duration;
6 
7pub struct DirectoryWatcher {
8 dir: PathBuf,
9 seen: HashSet<PathBuf>,
10 interval: Duration,
11}
12 
13impl DirectoryWatcher {
14 pub fn new(dir: impl Into<PathBuf>, interval: Duration) -> Self {
15 Self {
16 dir: dir.into(),
17 seen: HashSet::new(),
18 interval,
19 }
20 }
21 
22 pub fn run<F>(&mut self, mut on_new_file: F) -> std::io::Result<()>
23 where
24 F: FnMut(&Path),
25 {
26 loop {
27 for entry in fs::read_dir(&self.dir)? {
28 let path = entry?.path();
29 if !path.is_file() {
30 continue;
31 }
32 if self.seen.insert(path.clone()) {
33 on_new_file(&path);
34 }
35 }
36 thread::sleep(self.interval);
37 }
38 }
39}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A HashSet of already-seen paths turns a repeated full scan into an efficient new-only detector.
  2. 2Accepting a generic FnMut callback lets the watcher stay agnostic about what happens on each new file.
  3. 3impl Into<PathBuf> lets callers pass string literals or paths without manual conversion at the call site.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Polling a directory for new files in Rust — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code