无竞赛目录步行(C)
我需要走一个目录树并获取每个文件的stat值.我想在修改文件系统时安全地执行此操作.
在Python中,最好的选项是 C有一个新的filesystem API graduated from boost,它缓存了stat值但是doesn’t expose them(我需要访问st_dev).这不仅仅是一个头库,所以我无法解决这个问题. 我错过了一个不错的C选项,它使用fstatat并且不受Boost理想的不暴露特定于平台的调用的约束?或者是我最好的选择包裹nftw(甚至找到)? 解决方法
事实证明它很容易实现.
我从干项目中使用了libposix. #include <posix++.h> class Walker { public: void walk(posix::directory dir) { dir.for_each([this,dir](auto& dirent) { if (dirent.name == "." or dirent.name == "..") return; if (!handle_dirent(dirent)) return; struct stat stat; if (dirent.type == DT_DIR || dirent.type == DT_UNKNOWN) { int fd = openat( dir.fd(),dirent.name.c_str(),O_DIRECTORY|O_NOFOLLOW|O_NOATIME); if (fd < 0) { // ELOOP when O_NOFOLLOW is used on a symlink if (errno == ENOTDIR || errno == ELOOP) goto enotdir; if (errno == ENOENT) goto enoent; posix::throw_error( "openat","%d,"%s"",dir.fd(),dirent.name); } posix::directory dir1(fd); fstat(fd,&stat); if (handle_directory(dirent,fd,stat)) walk(dir1); close(fd); return; } enotdir: try { dir.stat(dirent.name.c_str(),stat,AT_SYMLINK_NOFOLLOW); } catch (const posix::runtime_error &error) { if (error.number() == ENOENT) goto enoent; throw; } handle_file(dirent,stat); return; enoent: handle_missing(dirent); }); } protected: /* return value: whether to stat */ virtual bool handle_dirent(const posix::directory::entry&) { return true; } /* return value: whether to recurse * stat will refer to a directory,dirent info may be obsolete */ virtual bool handle_directory( const posix::directory::entry &dirent,const int fd,const struct stat&) { return true; } /* stat might refer to a directory in case of a race; * it still won't be recursed into. dirent may be obsolete. */ virtual void handle_file( const posix::directory::entry &dirent,const struct stat&) {} /* in case of a race */ virtual void handle_missing( const posix::directory::entry &dirent) {} }; 性能与GNU find相同(当与基类进行比较时,使用-size $RANDOM来抑制输出并强制查找统计所有文件,而不仅仅是DT_DIR候选者). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |