FileWatch

An instance of a FileWatcher

Destructor

~this
~this()
Undocumented in source.

Members

Aliases

FollowSymlink
alias FollowSymlink = NamedType!(bool, Tag!"FollowSymlink", bool.init, TagStringable)
Undocumented in source.

Functions

getEvents
FileChangeEvent[] getEvents(Duration timeout)

The events that have occured since last query.

watch
bool watch(Path path, uint events)

Add a path to watch for events.

watch
bool watch(string p, uint events)
watchRecurse
AbsolutePath[] watchRecurse(Path root, uint events, bool delegate(string) pred)

Recursively add the path and all its subdirectories and files to be watched.

watchRecurse
AbsolutePath[] watchRecurse(string root, uint events, bool delegate(string) pred)

Examples

import core.thread;

if (exists("test"))
    rmdirRecurse("test");
scope (exit) {
    if (exists("test"))
        rmdirRecurse("test");
}

auto watcher = fileWatch();

mkdir("test");
assert(watcher.watch("test"));

write("test/a.txt", "abc");
auto ev = watcher.getEvents(5.dur!"seconds");
assert(ev.length > 0);
assert(ev[0].tryMatch!((Event.Create x) {
        assert(x.path == AbsolutePath("test/a.txt"));
        return true;
    }));

append("test/a.txt", "def");
ev = watcher.getEvents(5.dur!"seconds");
assert(ev.length > 0);
assert(ev[0].tryMatch!((Event.Modify x) {
        assert(x.path == AbsolutePath("test/a.txt"));
        return true;
    }));

rename("test/a.txt", "test/b.txt");
ev = watcher.getEvents(5.dur!"seconds");
assert(ev.length > 0);
assert(ev[0].tryMatch!((Event.Rename x) {
        assert(x.from == AbsolutePath("test/a.txt"));
        assert(x.to == AbsolutePath("test/b.txt"));
        return true;
    }));

remove("test/b.txt");
ev = watcher.getEvents(5.dur!"seconds");
assert(ev.length > 0);
assert(ev[0].tryMatch!((Event.Delete x) {
        assert(x.path == AbsolutePath("test/b.txt"));
        return true;
    }));

rmdirRecurse("test");
ev = watcher.getEvents(5.dur!"seconds");
assert(ev.length > 0);
assert(ev[0].tryMatch!((Event.DeleteSelf x) {
        assert(x.path == AbsolutePath("test"));
        return true;
    }));
1 import std.algorithm : canFind;
2 
3 if (exists("test2"))
4     rmdirRecurse("test2");
5 if (exists("test3"))
6     rmdirRecurse("test3");
7 scope (exit) {
8     if (exists("test2"))
9         rmdirRecurse("test2");
10     if (exists("test3"))
11         rmdirRecurse("test3");
12 }
13 
14 auto watcher = fileWatch();
15 mkdir("test2");
16 assert(watcher.watchRecurse("test2").length == 0);
17 
18 write("test2/a.txt", "abc");
19 auto ev = watcher.getEvents(5.dur!"seconds");
20 assert(ev.length == 3);
21 assert(ev[0].tryMatch!((Event.Create x) {
22         assert(x.path == AbsolutePath("test2/a.txt"));
23         return true;
24     }));
25 assert(ev[1].tryMatch!((Event.Modify x) {
26         assert(x.path == AbsolutePath("test2/a.txt"));
27         return true;
28     }));
29 assert(ev[2].tryMatch!((Event.CloseWrite x) {
30         assert(x.path == AbsolutePath("test2/a.txt"));
31         return true;
32     }));
33 
34 rename("test2/a.txt", "./testfile-a.txt");
35 ev = watcher.getEvents(5.dur!"seconds");
36 assert(ev.length == 1);
37 assert(ev[0].tryMatch!((Event.Delete x) {
38         assert(x.path == AbsolutePath("test2/a.txt"));
39         return true;
40     }));
41 
42 rename("./testfile-a.txt", "test2/b.txt");
43 ev = watcher.getEvents(5.dur!"seconds");
44 assert(ev.length == 1);
45 assert(ev[0].tryMatch!((Event.Create x) {
46         assert(x.path == AbsolutePath("test2/b.txt"));
47         return true;
48     }));
49 
50 remove("test2/b.txt");
51 ev = watcher.getEvents(5.dur!"seconds");
52 assert(ev.length == 1);
53 assert(ev[0].tryMatch!((Event.Delete x) {
54         assert(x.path == AbsolutePath("test2/b.txt"));
55         return true;
56     }));
57 
58 mkdir("test2/mydir");
59 rmdir("test2/mydir");
60 ev = watcher.getEvents(5.dur!"seconds");
61 assert(ev.length == 2);
62 assert(ev[0].tryMatch!((Event.Create x) {
63         assert(x.path == AbsolutePath("test2/mydir"));
64         return true;
65     }));
66 assert(ev[1].tryMatch!((Event.Delete x) {
67         assert(x.path == AbsolutePath("test2/mydir"));
68         return true;
69     }));
70 
71 // test for creation, modification, removal of subdirectory
72 mkdir("test2/subdir");
73 ev = watcher.getEvents(5.dur!"seconds");
74 assert(ev.length == 1);
75 assert(ev[0].tryMatch!((Event.Create x) {
76         assert(x.path == AbsolutePath("test2/subdir"));
77         // add the created directory to be watched
78         watcher.watchRecurse(x.path);
79         return true;
80     }));
81 
82 write("test2/subdir/c.txt", "abc");
83 ev = watcher.getEvents(5.dur!"seconds");
84 assert(ev.length == 3);
85 assert(ev[0].tryMatch!((Event.Create x) {
86         assert(x.path == AbsolutePath("test2/subdir/c.txt"));
87         return true;
88     }));
89 
90 write("test2/subdir/c.txt", "\nabc");
91 ev = watcher.getEvents(5.dur!"seconds");
92 assert(ev.length == 2);
93 assert(ev[0].tryMatch!((Event.Modify x) {
94         assert(x.path == AbsolutePath("test2/subdir/c.txt"));
95         return true;
96     }));
97 
98 rmdirRecurse("test2/subdir");
99 ev = watcher.getEvents(5.dur!"seconds");
100 assert(ev.length == 3);
101 foreach (e; ev) {
102     assert(ev[0].tryMatch!((Event.Delete x) {
103             assert(canFind([
104                 AbsolutePath("test2/subdir/c.txt"),
105                 AbsolutePath("test2/subdir")
106             ], x.path));
107             return true;
108         }, (Event.DeleteSelf x) {
109             assert(x.path == AbsolutePath("test2/subdir"));
110             return true;
111         }));
112 }
113 
114 // removal of watched folder
115 rmdirRecurse("test2");
116 ev = watcher.getEvents(5.dur!"seconds");
117 assert(ev.length == 1);
118 assert(ev[0].tryMatch!((Event.DeleteSelf x) {
119         assert(x.path == AbsolutePath("test2"));
120         return true;
121     }));

Meta