【问题标题】:Retrieve the full path name from inotify_event从 inotify_event 检索完整路径名
【发布时间】:2012-02-16 14:39:46
【问题描述】:

inotify_event 结构如下所示:

struct inotify_event {
int      wd;       /* Watch descriptor */
uint32_t mask;     /* Mask of events */
uint32_t cookie;   /* Unique cookie associating related
                      events (for rename(2)) */
uint32_t len;      /* Size of name field */
char     name[];   /* Optional null-terminated name */

};

名称部分只存储文件名(不是文件路径)。我们如何从 inotify_event 结构中获得完全限定的路径,还是我必须将我自己的结构包装起来?

编辑:我等待事件大约 2 秒,然后一次性处理它。我维护一个事件队列。我的问题是我是否只能从 inotify_event 结构中获取文件的完整路径?

每秒的事件数很大。

【问题讨论】:

    标签: c linux inotify


    【解决方案1】:

    有两种选择:

    1. 您正在观看一个文件。您已将其名称传递给inotify_add_watch,并获得了一个监视描述符。如果你得到一个事件,你可以通过监视描述符找出文件。

    2. 您正在查看目录。同样,您已将目录名称传递给 inotify_add_watch,并且可以根据监视 ID 找到它的名称。现在inotify_event.name 包含文件名。将两者连接起来就完成了。

    【讨论】:

    • 什么意思:“如果你得到一个事件,你可以通过监视描述符找出文件。”我将所有事件添加到队列中,大约 2 秒后,一次性处理它。
    • @FF 然后你应该添加一个关于被监控路径的提示。
    • 每次添加事件时,您都有一个名称(您刚刚传递给 inotify_add_watch 和一个描述符(您作为返回值获得)。您需要将这对保存在一些数据中结构。稍后,当你有一个监视描述符时,查看那里并找到关联的名称。
    • 好的,所以需要维护一对。但是可能我的程序可能会运行很长时间,并且文件可能会从一个目录移动到另一个目录、修改、删除等。是否保证我得到的 wd 将指向同一个文件?
    • 不,如果文件/目录被重命名/移动,您必须使用 inotify_event cookie,它就是为了这个目的而存在的,并且保证不会改变。并且您需要监控 IN_MOVED_* 事件。
    【解决方案2】:

    我认为您需要在将每个监视描述符添加到某个结构时跟踪它们(添加时都带有完整路径)。然后,当您收到事件时,使用事件中的 wd 查找该结构中的完整路径。

    wd 标识发生此事件的手表。它是其中之一 由先前调用 inotify_add_watch(2) 返回的监视描述符。

    http://www.kernel.org/doc/man-pages/online/pages/man7/inotify.7.html

    希望对您有所帮助...

    【讨论】:

      【解决方案3】:

      将生成的监视描述符与您添加的要监视的路径关联(使用结构)。因此,您将创建一个手表列表。当您获得一个事件时,它包含监视描述符,因此,您将从监视列表中找到与此监视描述符关联的路径。将从事件结构中获得的名称与从手表列表中获得的路径连接起来。此外,当您添加要观看的路径时,此时您还将以与添加父路径相同的方式递归添加所有子路径。

      【讨论】:

        【解决方案4】:

        就目前而言,这没问题,但这不是全部答案。

        如果您有一个目录结构并且您正在观看文件和目录事件,并且它看起来像这样:/root/dir1 和 /root/dir2,那么您将无法正确解析在 dir1 中创建文件或目录的位置或 dir2,即使您将它们添加到监视列表中也是如此。

        Inotify 返回项目的名称,但不会告诉您它在哪个目录中。

        【讨论】:

          【解决方案5】:

          inotify 系统使用连续数字作为监视描述符,假设您要监视 3 个目录, ../A 、 ../B 和 ../C ,如果可以说,我在里面创建一个文件../A ,那么从 read() 返回的监视描述符将为 1.,如果我在 ../C 中创建一个文件,则监视描述符将为 3,依此类推。因此,关联非常简单,您可以使用路径创建一个数组,并将 inotify_add_watch() 应用于每个路径,然后,如果事件具有监视描述符 x,只需将 pathsArray[x-1] 与事件->名称,你有路径:)

          std::string getPathFromEvent(struct inotify_event *ptr){
              std::stringstream builder ;
              builder<<directories->DetectedDirectories.operator[](ptr->wd-1).string();
              builder<<ptr->name;
              return builder.str();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-11
            • 1970-01-01
            • 2015-01-21
            • 2014-04-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多