在Python中,最好的选项是os.fwalk
,它允许访问被遍历目录的fd;然后我可以使用dir_fd(fstatat)os.stat并获取当前的stat值.这是可以在linux上进行的无竞争(如果正在修改此目录的内容,我可能需要重新扫描它).在C中,有nftw
,它是类似地实现的,而fts
,在glibc中使用plain(l)stat,因此是racy(它通过改变目录来减少竞争窗口,这是不方便的).
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候选者).
总结以上是内存溢出为你收集整理的无竞赛目录步行(C)全部内容,希望文章能够帮你解决无竞赛目录步行(C)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)