可以监视目录变化的小程序
这是我在写 Cikada 时遇到的一个小问题,发现利用 GIO 库的 GFileMonitor 类与 GLib 提供的 GMainLoop 主循环可以很方便的解决它。
#include <gio/gio.h> static void dir_is_changed (GFileMonitor *monitor, GFile *file, GFile *other, GFileMonitorEvent event_type, gpointer user_data) { if (event_type == G_FILE_MONITOR_EVENT_CREATED) g_print ("You just created '%s'!\n", g_file_get_path (file)); } int main (int argc, char **argv) { g_type_init (); GMainLoop *main_loop = g_main_loop_new (NULL, TRUE); GFile *file = g_file_new_for_path ("/tmp/cikada"); GFileMonitor * monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); g_signal_connect (monitor, "changed", (GCallback)dir_is_changed, NULL); g_main_loop_run (main_loop); g_object_unref (file); g_main_loop_unref (main_loop); return 0; }
上述代码的大意是:
- 使用 g_file_monitor_directory 为 "/tmp/cikada" 目录设定监控器 monitor,然后将 "changed" 信号及其处理函数 dir_is_changed 挂到 monitor 上。
- 运行主循环,等待来自 "/tmp/cikada" 目录的事件。如果这个目录发生了文件被创建、删除、重命名等操作,那么 "changed" 信号便会被触发,dir_is_changed 函数便会被调用。
- dir_is_changed 函数中,我只对文件被创建的事件感兴趣,所以忽略了其他事件。
编译并运行这个程序:
$ gcc `pkg-config --cflags --libs gio-2.0` test.c -o test $ ./test
然后在 /tmp/cikada 目录里随便建一些文件,这个程序便会咕噜出类似以下信息:
You just created '/tmp/cikada/4'! You just created '/tmp/cikada/5'! You just created '/tmp/cikada/6'!
如果要监视一个文件的变化,那么可以将 g_file_monitor_directory 替换为 g_file_monitor。
更多的信息请阅读:
- http://developer.gnome.org/gio/stable/GFileMonitor.html
- http://developer.gnome.org/gio/stable/GFile.html
转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com
2012年5月31日 08:58
I'd prefer to use inotify (man 7 inotify).
2012年5月31日 09:55
@tubo: 嗯。gio 库的文件监视功能在 linux 平台中貌似就是封装的 inotify。
2013年7月31日 21:56
我比较关心的是,能否递归监控,比如监控/tmp/cikada,那么如果创建 了文件
/tmp/cikada/1/2/3/4 能否监控到。
貌似inotify做不到这一点
2013年7月31日 21:57
如果做不到的话,其实用inotify 或者fanotify都不错,封装一层没啥必要了。
2013年8月01日 20:40
@manuscola: 没法递归监控。