将 Cikada 推倒重来
Cikada 0.5 发布

可以监视目录变化的小程序

Garfileo posted @ 2012年5月30日 15:09 in 业余程序猿的足迹 with tags gio GFileMonitor , 4283 阅读

这是我在写 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

  • 无匹配
  • 无匹配
tubo 说:
2012年5月31日 08:58

I'd prefer to use inotify (man 7 inotify).

Avatar_small
Garfileo 说:
2012年5月31日 09:55

@tubo: 嗯。gio 库的文件监视功能在 linux 平台中貌似就是封装的 inotify。

manuscola 说:
2013年7月31日 21:56

我比较关心的是,能否递归监控,比如监控/tmp/cikada,那么如果创建 了文件
/tmp/cikada/1/2/3/4 能否监控到。

貌似inotify做不到这一点

manuscola 说:
2013年7月31日 21:57

如果做不到的话,其实用inotify 或者fanotify都不错,封装一层没啥必要了。

Avatar_small
rca 说:
2013年8月01日 20:40

@manuscola: 没法递归监控。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter