加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用stat来检测文件是否存在(慢?)

发布时间:2020-12-16 04:57:36 所属栏目:百科 来源:网络整理
导读:我正在使用类似下面的代码来检查文件是否在继续之前已经创建了,事情是文件在文件浏览器中显示的内容很多,然后才被stat检测到…这样做有问题吗? //... do somethingstruct stat buf;while(stat("myfile.txt",buf)) sleep(1);//... do something else 或者有
我正在使用类似下面的代码来检查文件是否在继续之前已经创建了,事情是文件在文件浏览器中显示的内容很多,然后才被stat检测到…这样做有问题吗?
//... do something

struct stat buf;

while(stat("myfile.txt",&buf))
  sleep(1);

//... do something else

或者有更好的方法来检查文件是否存在?

解决方法

“stat”系统调用正在收集关于文件的不同信息,例如指向它的许多硬链接或其“inode”号.您可能希望查看“访问”系统调用,您可以使用该调用仅通过在“模式”中指定“F_OK”标志来执行存在检查.

但是,您的代码有一点问题.每次检查尚不存在的文件时,它会使进程休眠一秒钟.为避免这种情况,您必须按照Jerry Coffin的建议使用inotify API,以便在您等待的文件存在时通过内核获得通知.请记住,如果文件已存在,inotify不会通知您,因此实际上您需要同时使用“access”和“inotify”来避免在创建文件后立即开始查看文件时出现竞争情况.

没有更好或更快的方法来检查文件是否存在.如果您的文件浏览器仍然显示该文件比该程序检测到的文件稍快,那么Greg Hewgill关于重命名的想法可能正在发生.

下面是一个C代码示例,用于设置inotify监视,检查文件是否已存在并等待它:

#include <cstdio>
#include <cstring>
#include <string>

#include <unistd.h>
#include <sys/inotify.h>

int
main ()
{
    const std::string directory = "/tmp";
    const std::string filename = "test.txt";
    const std::string fullpath = directory + "/" + filename;

    int fd = inotify_init ();
    int watch = inotify_add_watch (fd,directory.c_str (),IN_MODIFY | IN_CREATE | IN_MOVED_TO);

    if (access (fullpath.c_str (),F_OK) == 0)
    {
        printf ("File %s exists.n",fullpath.c_str ());
        return 0;
    }

    char buf [1024 * (sizeof (inotify_event) + 16)];
    ssize_t length;

    bool isCreated = false;

    while (!isCreated)
    {
        length = read (fd,buf,sizeof (buf));
        if (length < 0)
            break;
        inotify_event *event;
        for (size_t i = 0; i < static_cast<size_t> (length);
             i += sizeof (inotify_event) + event->len)
        {
            event = reinterpret_cast<inotify_event *> (&buf[i]);
            if (event->len > 0 && filename == event->name)
            {
                printf ("The file %s was created.n",event->name);
                isCreated = true;
                break;
            }
        }
    }

    inotify_rm_watch (fd,watch);
    close (fd);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读