我正在寻找使用sqlite db同步某些目录中文件的最佳方法。
首先,我使用一个递归查找按扩展名筛选的文件的线程,并添加它们执行我的数据库。 接下来,我使用QFileSystemWatcher来观察文件是否发生变化并且运行良好。
问题在于,每次运行应用程序时,我都不知道文件是否已更改,因此我需要运行该线程,并且在执行期间(大约1分钟)需要100%的cpu(<1分钟)
那么我该如何改进这个算法呢? 感谢
此致 A993
编辑:
代码是一个递归函数,类似于我用来计算目录中文件的函数(也是这个函数需要100%的cpu)
int MediaScan_Thread::recursiveCount(QDir &dir)
{
int i=dir.entryInfoList(_filters,QDir::Files).count();
foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot))
{
QDir subdir(info.absoluteFilePath());
i += recursiveCount(subdir);
}
return i;
}
我正在开发linux,但我会开发一个多平台应用程序。
答案 0 :(得分:0)
我将迭代一个entryList()列表,递归目录并检查文件上的文件过滤器。没有一种简单的方法可以通过多个线程递归搜索文件列表。但是一旦你获得文件列表,就可以很容易地进行并行处理。
我将计数和文件列表的调用合并到I / O上的一次命中,因为没有任何理由这样做两次。此版本将跟踪查询的QStringList
,以便稍后进行更多处理。
在递归函数上使用foreach可能会有问题,因为列表的副本已经生成,因此我切换到使用带迭代器的for循环。
特殊添加是模仿QDir nameFilters功能,因为entryList()接受一个fileFilters参数,它用于目录和文件(不是我们想要的)。
我省略的一个功能是递归深度限制,以避免永远搜索。
此代码示例已编译但未经过测试
// declare in MediaScan_Thread and set them in constructor or wherever it needs to be:
QVector<QRegExp> _nameRegExps;
QStringList _filters;
QDir::Filters _dirFilters;
// ....
void MediaScan_Thread::initFilterRegExp()
{
_nameRegExps.clear();
for (int i = 0; i < _filters.size(); ++i)
{
_nameRegExps.append( QRegExp(_filters.at(i), (_dirFilters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard) );
}
}
int MediaScan_Thread::recursiveCountAndMatchedFiles(QDir &dir, QStringList& matchedFiles )
{
int i = 0;
QFileInfoList lst = dir.entryInfoList( QStringList() , QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot );
for ( auto itr = lst.begin(); itr != lst.end(); itr++ )
{
QFileInfo &info = (*itr);
if (info.isDir())
i += recursiveCountAndMatchedFiles( info.absoluteDir(), matchedFiles );
else
{
QString fileName = info.absoluteFilePath();
for (auto iter = _nameRegExps.constBegin(), end = _nameRegExps.constEnd();
iter != end; ++iter)
{
if (iter->exactMatch(fileName)) {
i++;
matchedFiles << fileName;
break;
}
}
}
}
return i;
}