我想使用nftw遍历C中的目录结构。
然而,考虑到我想要做的事情,我看不到使用全局变量的方法。
使用(n)ftw的教科书示例都涉及到打印文件名之类的操作。相反,我希望获取路径名和文件校验和,并将它们放入数据结构中。但是,考虑到可以传递给nftw的内容的限制,我看不到这样做的好方法。
我使用的解决方案涉及一个全局变量。然后,nftw调用的函数可以访问该变量并添加所需的数据。
在不使用全局变量的情况下,有什么合理的方法可以做到这一点吗?
发布于 2014-04-21 23:28:59
使用ftw可能是非常非常糟糕的。在内部,它将保存你使用的函数指针,如果另一个线程做了其他事情,它将覆盖函数指针。
恐怖场景:
线程1:数十亿个文件线程2:删除一些文件线程1:-oops,它现在正在删除数十亿个文件,而不是计算它们。
总之。您最好使用fts_open。
如果您仍然想使用nftw,那么我的建议是将“全局”类型放在一个名称空间中,并将其标记为"thread_local“。您应该能够根据自己的需要进行调整。
/* in some cpp file */
namespace {
thread_local size_t gTotalBytes{0}; // thread local makes this thread safe
int GetSize(const char* path, const struct stat* statPtr, int currentFlag, struct FTW* internalFtwUsage) {
gTotalBytes+= statPtr->st_size;
return 0; //ntfw continues
}
} // namespace
size_t RecursiveFolderDiskUsed(const std::string& startPath) {
const int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS;
const int maxFileDescriptorsToUse = 1024; // or whatever
const int result = nftw(startPath.c_str(), GetSize, maxFileDescriptorsToUse , flags);
// log or something if result== -1
return gTotalBytes;
}发布于 2012-04-23 21:26:03
不是的。nftw没有提供任何可以传递给函数的用户参数,因此您必须使用C语言中的全局(或静态)变量。
GCC提供了一个扩展“嵌套函数”,它应该捕获其封闭作用域的变量,因此可以这样使用它们:
void f()
{
int i = 0;
int fn(const char *,
const struct stat *, int, struct FTW *) {
i++;
return 0;
};
nftw("path", fn, 10, 0);
}发布于 2012-04-23 21:40:52
最好在单独的模块中为数据提供静态链接(即文件范围),该模块只包含访问数据所需的函数,包括传递给nftw()的函数。这样,数据就不会在全局范围内可见,并且所有访问都受到控制。调用ntfw()的函数也可能是此模块的一部分,从而使传递给nftw()的函数也是静态的,因此在外部不可见。
换句话说,您应该做您可能已经在做的事情,但要明智地使用单独的编译和静态链接,使数据只能通过access函数可见。具有静态链接的数据可由同一转换单元中的任何函数访问,并且只需在该转换单元中包含作为该数据的创建者、维护者或访问者的函数,即可避免与全局变量相关的问题。
一般的模式是:
datamodule.h
#if defined DATAMODULE_INCLUDE
<type> create_data( <args>) ;
<type> get_data( <args> ) ;
#endifdatamodule.c
#include "datamodule.h"
static <type> my_data ;
static int nftwfunc(const char *filename, const struct stat *statptr, int fileflags, struct FTW *pfwt)
{
// update/add to my_data
...
}
<type> create_data( const char* path, <other args>)
{
...
ret = nftw( path, nftwfunc, fd_limit, flags);
...
}
<type> get_data( <args> )
{
// Get requested data from my_data and return it to caller
}https://stackoverflow.com/questions/10281198
复制相似问题